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;

    }

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

  • 相关阅读:
    第06组 Alpha事后诸葛亮
    第06组 Alpha冲刺(6/6)
    第06组 Alpha冲刺(5/6)
    2020ASE-课程总结
    设计也可以按图索骥
    2020ASE第二次博客—由需求分析来看软件开发的挑战
    2020ASE第一次课程作业—期望与笃信
    git学习笔记(1)
    课程模块——课程界面与技术文档
    企业应用开发(5)--ERD初步设计
  • 原文地址:https://www.cnblogs.com/ranyang/p/13843344.html
Copyright © 2011-2022 走看看