平衡二叉树旋转,删除,插入

#include <stdio.h>
#include <malloc.h>

#define true 1
#define false 0
#define MaxDataNum 100

struct AVLTreeStruct {
    int data;
    int height;//我不知道这个有什么用,或许有更好的优化方法。
    struct AVLTreeStruct* left;
    struct AVLTreeStruct* right;
};
struct QueueStruct {
    int Capacity;
    int Rear, Front;
    struct AVLTreeStruct* Array[MaxDataNum];
};
typedef struct AVLTreeStruct* AVLTree;
typedef AVLTree TNode;
typedef struct QueueStruct* Queue;

TNode createTNode();
void initializeTNode( TNode t );
void printfError();
AVLTree insertAVLTree( AVLTree TreeHead, int data );
AVLTree RRotation( AVLTree PreviousTreeHead );
AVLTree LRotation( AVLTree PreviousTreeHead );
AVLTree RLRotation( AVLTree PreviousTreeHead );
AVLTree LRRotation( AVLTree PreviousTreeHead );
AVLTree deleteAVLTreeNode( AVLTree TreeHead, TNode Node );
TNode findMaxNode( AVLTree TreeHead );
TNode findMinNode( AVLTree TreeHead );
void drawATree( AVLTree TreeHead );
void enQueue( Queue q, TNode n );
TNode deQueue( Queue q );
int judgeNotChild( Queue q );
int Max( int a, int b );
int Height( AVLTree TreeHead );


int main( void ) {
    int i = 0;
    int data = 0;
    int n = 20;
    TNode tmp = createTNode();
    AVLTree t = createTNode();
    initializeTNode( t );
    initializeTNode( tmp );

    for( i = 0; i < n; i++ ) {
        scanf("%d", &data);
        if( i == 0 ) {
            t->data = data;
        }
        else {
            t = insertAVLTree( t, data );
        }
    }

    drawATree( t );
    printf("\n");
    
    TNode m = t;
    for( i = 0; i < n; i++ ) {
        scanf("%d", &tmp->data);
        t = deleteAVLTreeNode( t, tmp );
        drawATree( t );
        printf("\n");
    }

    return 0;
}

void printfError() {
    printf("Space Error!");
    exit(0);
}
TNode createTNode() {

    TNode t = ( TNode )malloc( sizeof(struct AVLTreeStruct) );
    if( !t ) {
        printfError();
    }

    return t;
}
void initializeTNode( TNode t ) {

    t->data = 0;
    t->left = t->right = NULL;
}
AVLTree RRotation( AVLTree PreviousTreeHead ) {
    TNode p = PreviousTreeHead;
    AVLTree t = p->left;

    p->left = t->right;
    t->right = p;

    return t;
}
AVLTree LRotation( AVLTree PreviousTreeHead ) {
    TNode p = PreviousTreeHead;
    AVLTree t = p->right;

    p->right = t->left;
    t->left = p;

    return t;
}
AVLTree RLRotation( AVLTree PreviousTreeHead ) {
    TNode p = PreviousTreeHead;

    p->right = RRotation( p->right );
    return LRotation( p );
}
AVLTree LRRotation( AVLTree PreviousTreeHead ) {
    TNode p = PreviousTreeHead;

    p->left = LRotation( p->left );
    return RRotation( p );
}
AVLTree insertAVLTree( AVLTree TreeHead, int data ) {
    AVLTree t = TreeHead;
    int d = data;
    AVLTree tmp1;

    if( t == NULL ) {
        t = createTNode();
        initializeTNode( t );
        t->data = d;
        return t;
    }

    if( d == t->data ) {
        return t;
    }
    if( d < t->data ) {
        t->left = insertAVLTree( t->left, d );

        if( Height(t->left) - Height(t->right) == 2 ) {
            tmp1 = t->left;//这样写是不是不好?

            t = Height(tmp1->left) >= Height(tmp1->right) ? RRotation( t ) : LRRotation( t );
        }
    }
    else {
        t->right = insertAVLTree( t->right, d );

        if( Height(t->right) - Height(t->left) == 2 ) {
            tmp1 = t->right;
            t = Height(tmp1->right) >= Height(tmp1->left) ? LRotation( t ) : RLRotation( t );
        }
    }

    return t;
}
int Height( AVLTree TreeHead ) {
    TNode t = TreeHead;

    if( !t ) {
        return 0;
    }

    return Max( Height(t->left), Height(t->right) ) + 1;

}
int Max( int a, int b ) {
    return a > b ? a : b;
}
AVLTree deleteAVLTreeNode( AVLTree TreeHead, TNode Node ) {

    AVLTree t = TreeHead;
    TNode n = Node;

    if( t == NULL || n == NULL ) {
        printf("Not Found!\n");
        return NULL;
    }

    if( n->data < t->data ) {
        t->left = deleteAVLTreeNode( t->left, n );

        if( Height(t->right) - Height(t->left) == 2 ) {
            t = Height(t->right->right) >= Height(t->right->left) ?  LRotation( t ) : RLRotation( t );
        }
    }
    else if( n->data > t->data ) {
        t->right = deleteAVLTreeNode( t->right, n );

        if( Height(t->right) - Height(t->right) == 2 ) {
            t = Height(t->left->left) >= Height(t->left->right) ?  RRotation( t ) : LRRotation( t );
        }
    }
    else {
        if( t->left && t->right ) {
            if( Height(t->left) >= Height(t->right) ) {//好像可以优化。
                TNode MaxNode = findMaxNode( t->left );
                t->data = MaxNode->data;
                t->left = deleteAVLTreeNode( t->left, MaxNode );
            }
            else {
                TNode MinNode = findMinNode( t->right );
                t->data = MinNode->data;
                t->right = deleteAVLTreeNode( t->right, MinNode );
            }
        }
        else {
            TNode tmp = t->right ? t->right : t->left;
            free( t );
            t = tmp;
        }
    }

    return t;
}
TNode findMaxNode( AVLTree TreeHead ) {
    TNode LastNode = NULL;
    AVLTree t = TreeHead;

    while( t ) {
        LastNode = t;
        t = t->right;
    }

    return LastNode;
}
TNode findMinNode( AVLTree TreeHead ) {
    TNode LastNode = NULL;
    AVLTree t = TreeHead;

    while( t ) {
        LastNode = t;
        t = t->left;
    }

    return LastNode;
}
void drawATree( AVLTree TreeHead ) {
    AVLTree t = TreeHead;
    TNode tmp = NULL;
    if( !t ) {
        return;
    }

    Queue q = ( Queue )malloc( sizeof(struct QueueStruct) );
    if( !q ) {
        printfError();
    }
    q->Front = q->Rear = 0;
    int num = 0;

    enQueue( q, t );
    printf("%d\n", t->data);

    while( !judgeNotChild( q ) ) {
        num = q->Rear-q->Front > 0 ? q->Rear - q->Front : q->Rear+MaxDataNum - q->Front;

        while( num ) {
            t = deQueue( q );
            tmp = t->left;
            if( tmp ) {
                printf("%d ", tmp->data);
                enQueue( q, tmp );
            }
            else {
                printf(" ");
            }
            tmp = t->right;
            if( tmp ) {
                printf("%d ", tmp->data);
                enQueue( q, tmp );
            }
            else {
                printf(" ");
            }
            num--;
        }
        printf("\n");
    }

}
void enQueue( Queue q, TNode n ) {
    if( (q->Rear+1) % MaxDataNum == q->Front ) {
        printf("IsFull!\n");
        return;
    }

    q->Rear = (q->Rear+1) % MaxDataNum;
    q->Array[q->Rear] = n;
}
TNode deQueue( Queue q ) {
    if( q->Front  == q->Rear ) {
        printf("IsEmpty\n");
        return NULL;
    }
    q->Front = (q->Front+1) % MaxDataNum;
    return q->Array[q->Front];
}
int judgeNotChild( Queue q ) {
    int i = (q->Front+1) % MaxDataNum;
    int num = q->Rear-q->Front > 0 ? q->Rear - q->Front : q->Rear+MaxDataNum - q->Front;
    AVLTree n = NULL;
    while( num ) {
        n = q->Array[i];
        if( n->left || n->right ) {
            break;
        }
        i++;
        num--;
    }

    if( !num ) {
        return true;
    }
    return false;
}


不会用Github。这个星期应该会去学。代码写了300多行,感觉就变成了怪物。重构的知识,只会一点。勉强,把代码量弄少一点,多写多思考,为了看我的平衡二叉树有没有问题,我还是写了一个层序遍历。代码好丑啊。

    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/TenShine/article/details/79264852
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞