zoukankan      html  css  js  c++  java
  • 第四章-平衡二叉树

    我们为了解决二叉树的查找,我们构建出了二叉搜索树(左子树小于其父结点,右子树大于其父结点)。但是这样显然是不够的,这样的查找太过于笨重,我们就想出了二叉平衡树:

    就是一个结点的左右子树高度差不能等于2,当等于2时,我们就对它进行平衡,这样减少了极端情况,可以明显的缩小查找的时间,二叉平衡在插入的时候会出现四种情况——LL,RR,LR,RL。下面我们用代码进行说明:

    #include <stdio.h>
    #include <stdlib.h>

    typedef struct TNode {
        int data;
        struct TNode *left;
        struct TNode *right;
        int height;
    }TNode,*Tree;

    typedef struct QNode {
        Tree data;
        int top;
        int base;
        int maxsize;
    }QNode,*Queue;

    void InitQueue (Queue *q);//初始化队列。
    void En (Queue q, Tree T);//进队。
    Tree De (Queue q);//出队。
    int IsFull (Queue q);//判断是否为满。
    int IsEmpty (Queue q);//判断是否为空。
    void Level (Tree T);//层次遍历二叉树。

    void Level (Tree T)//层次遍历是用来检验二叉树是否平衡正确。
    {
        Queue q;
        InitQueue (&q);
        En(q,T);
        Tree temp;
        while(!IsEmpty(q)) {
            temp = De(q);
            printf("%d ",temp->data);
            if(temp->left) En(q,temp->left);
            if(temp->right) En(q,temp->right);
        }
    }

    void InitQueue (Queue *q)
    {
        (*q) = (QNode*) malloc(sizeof(QNode));
        (*q)->top = (*q)->base = 0;
        (*q)->maxsize = 10;
        (*q)->data = (Tree) malloc(sizeof(TNode) * (*q)->maxsize);
    }

    int IsFull(Queue q)
    {
        return ((q->top + 1) % (q->maxsize - 1) == q->base);
    }

    int IsEmpty (Queue q)
    {
        return (q->base == q->top);
    }

    void En (Queue q, Tree T)
    {
        if (IsFull(q)) {
            printf("The queue is full! ");
        }else {
            TNode *temp;
            temp = T;
            q->data[q->top] = *temp;
            q->top = (q->top + 1) % (q->maxsize -1 );

        }
    }


    Tree De (Queue q)
    {
        if(IsEmpty(q)) {
            printf("The queue is empty! ");
        }else {
            Tree T;
            T = &(q->data[q->base]);
            q->base = (q->base + 1) % (q->maxsize - 1);
            return T;
        }
    }

    int Height (Tree T)//返回当前结点的高度。
    {
        if(!T) {
            return -1;
        }else {
            return T->height;
        }
    }

    int Max (int a, int b)//返回a,b中最大的数字
    {
        return a>b?a:b;
    }

    Tree RotateWithLeft (Tree T)//左旋转来平衡该结点。
    {
        Tree temp;
        temp = T->left;
        T->left = temp->right;
        temp->right = T;

        T->height = Max(Height(T->left),Height(T->right)) + 1;
        temp->height = Max (Height(temp->left),Height(temp->right)) + 1;

        return temp;
    }

    Tree RotateWithRight (Tree T)//右旋转平衡该结点。
    {
        Tree temp;
        temp = T->right;
        T->right = temp->left;
        temp->left = T;

        T->height = Max(Height(T->left),Height(T->right)) + 1;//更新T的高度。
        temp->height = Max(Height(temp->left),Height(temp->right)) + 1;//更系temp结点的高度。

        return temp;
    }

    Tree RotateWithLeftRight (Tree T)//左右旋转平衡。
    {
        T->left = RotateWithRight(T->left);

        return (RotateWithLeft(T));
    }

    Tree RotateWithRightLeft (Tree T)//RL旋转平衡。
    {
        T->right = RotateWithLeft (T->right);

        return RotateWithRight(T);
    }

    Tree Insert (int x, Tree T)
    {
        if (!T) {//若结点为空,则生成新结点。
            T = malloc(sizeof(TNode));
            T->data = x;
            T->height = 0;
            T->left = T->right = NULL;
        }else if (x < T->data) {//小于的话,则插入左子树。
            T->left = Insert (x,T->left);
            if (Height(T->left) - Height(T->right) == 2) {//插入后,若左右子树的高度差等于2,则进行平衡。
                if (x < T->left->data) {//若小于,肯定属于LL旋转。
                    T = RotateWithLeft (T);
                }else {//否则属于LR旋转。
                    T = RotateWithLeftRight(T);
                }
            }
        }else if (x > T->data) {//大于就插入右子树。
            T->right = Insert (x,T->right);
            if (Height(T->right) - Height(T->left) == 2){
                if (x > T->right->data) {//若大于,同上。
                    T = RotateWithRight(T);
                }else {
                    T = RotateWithRightLeft(T);//同上。
                }
            }
        }

        T->height = Max(Height(T->left),Height(T->right)) + 1;//完成后,我们需要更新该结点的高度。

        return T;

    }

    int main ()//测试函数。
    {
        Tree T;
        int i;
        for( i =1 ;i < 10;i++) {
            T = Insert (i,T);
            //printf("data is %d",T->data);
        }
        
        Level (T);

        return 0;

    }

    今天就写到这里吧,期待下一次!

  • 相关阅读:
    HDU 3401 Trade
    POJ 1151 Atlantis
    HDU 3415 Max Sum of MaxKsubsequence
    HDU 4234 Moving Points
    HDU 4258 Covered Walkway
    HDU 4391 Paint The Wall
    HDU 1199 Color the Ball
    HDU 4374 One hundred layer
    HDU 3507 Print Article
    GCC特性之__init修饰解析 kasalyn的专栏 博客频道 CSDN.NET
  • 原文地址:https://www.cnblogs.com/ranyang/p/13843344.html
Copyright © 2011-2022 走看看