平衡二叉树构建(非递归,利用高度差平衡)

平衡思路

        1.分别求出当前节点的父节点的左子树右子树高度。,利用高度差推断是否打破平衡。

        2.有四种情况(LL,LR,RR,LR

               •  左子树-右子树=1
                        在左子树的左子树上插入,LL型,右旋。 
                        在左子树的右子树上插入,LR型,先左旋后右旋。
               •  左子树-右子树=-1
                        在右子树的左子树上插入,RL,先右旋后左旋。 
                        在右子树的右子树上插入,RR,左旋。  

代码

   平衡二叉树

#include <stdio.h>

#include <stdlib.h>

typedef struct TreeB

{

    int data;

    struct TreeB *parent;//父节点

    struct TreeB *lchild;

    struct TreeB *rchild;

}TreeB;

typedef struct BTree

{

    TreeB *root;//根节点

    int len;

}BTree;

//用于层次遍历二叉排序树的队列

typedef struct Quee{

    TreeB *tb;

    struct Quee *next;

}Quee;

typedef struct TQuee{

    Quee *front;

    Quee *behind;

    int length;

}TQuee;

int init_TQuee(TQuee *s){

    s->front=s->behind=(Quee *)malloc(sizeof(Quee));

    s->length=0;

    return 1;

}

int push_Quee(TQuee *s,TreeB *t){

    Quee *p;

    p=(Quee *)malloc(sizeof(Quee));

    p->tb=t;

    p->next=NULL;

    s->behind->next=p;

    s->behind=p;

    return 1;

}

TreeB* pop_Quee(TQuee *s){

    Quee *p;TreeB *t;

    if(s->front->next==s->behind){

        p=s->behind;

        t=p->tb;

        s->behind=s->front;

        p->tb=NULL;

        free(p);

    }else{

        p=s->front->next;

        t=p->tb;

        s->front->next=p->next;

        p->tb=NULL;

        free(p);

    }

    return t;

}//结束  

//初始化树

int init_Btree(BTree *bt){

    bt->root=(TreeB *)malloc(sizeof(TreeB));

    bt->len=0;

    bt->root->lchild=NULL;

    bt->root->rchild=NULL;

    return 0;

}

//平衡查找树插入节点

int insert_SortTree(BTree *bt,int a){

    TreeB *p;

    int h1=0,h2=0,n;

    n=bt->len;

    //第一次插入

    if(bt->len==0){

        bt->root->data=a;

        bt->root->parent=NULL;

        bt->len++;

    }

   

    p=bt->root;

   

    while (n)

    {

       

        if(a>p->data){

           

            if(p->rchild){

                n--;

                p=p->rchild;

            }

            else{

               //求高度差

                if(p->parent){

                    if(p->parent->lchild) h1=getTHeight(p->parent->lchild,1);

                    else h1=0;

                    if(p->parent->rchild) h2=getTHeight(p->parent->rchild,1);

                    else h2=0;

                }

                p->rchild=(TreeB *)malloc(sizeof(TreeB));

                p->rchild->data=a;

                p->rchild->parent=p;

                p->rchild->lchild=NULL;

                p->rchild->rchild=NULL;

               

                if(h1-h2==1){

                    //LR

                    if(h2==0){//h2等于0相当于看在左子树插入还是右子树插入 下同

                        TreeB *q,*t;

                        q=p->rchild;t=p->parent;

                        t->lchild=q;q->lchild=p;p->rchild=NULL;

                        p->parent=q;q->parent=t;

                        q->rchild=t;t->lchild=NULL;

                        q->parent=t->parent;

                        //平衡后树被打散,拼接 下同

                        if(!q->parent){

                            bt->root=q;

                        }else{

                            if(q->parent->rchild){

                                if(q->parent->rchild==t) q->parent->rchild=q;

                            }else{

                               if(p->parent->lchild==t) q->parent->lchild=q;

                            }

                        }

                        t->parent=q;

                    }  

                       

                }else if(h1-h2==0){

                }else{//RR

                    if(h1==0){

                        TreeB *t;

                        t=p->parent;p->lchild=t;

                        p->parent=t->parent;

                        if(!p->parent){

                                bt->root=p;

                        }else{

                            if(p->parent->rchild){

                                if(p->parent->rchild==t) p->parent->rchild=p;

                            }else{

                            if(p->parent->lchild==t) p->parent->lchild=p;

                            }

                        }

                        t->parent=p;

                        t->rchild=NULL;

                    }

                }

                bt->len++;

                return 1;

            }

           

        }

        else if(a<p->data){

           

            if(p->lchild){

               n--;

               p=p->lchild;  

            }

            else{

               

                if(p->parent){

                   

                    if(p->parent->lchild) h1=getTHeight(p->parent->lchild,1);

                    else h1=0;

                    if(p->parent->rchild) h2=getTHeight(p->parent->rchild,1);

                    else h2=0;

                }

               

                p->lchild=(TreeB *)malloc(sizeof(TreeB));

                p->lchild->data=a;

                p->lchild->parent=p;

                p->lchild->lchild=NULL;

                p->lchild->rchild=NULL;

                if(h1-h2==1){//LL

                    if(h2==0){

                        TreeB *t;

                        t=p->parent;

                        printf("hh%d\n",p->parent->data);

                        p->rchild=t;

                        p->parent=t->parent;

                   

                        if(!p->parent){

                            bt->root=p;

                        }else{

                       

                            if(p->parent->rchild){

                                if(p->parent->rchild==t) p->parent->rchild=p;

                            }else{

                                if(p->parent->lchild==t)  p->parent->lchild=p;

                            }

                        }

                    t->parent=p;

                    t->lchild=NULL;

                    }

                }else if(h1-h2==0){

                }else{//RL

                    if(h1==0){

                        TreeB *q,*t;

                        q=p->rchild;t=p->parent;

                        t->rchild=q;q->rchild=p;

                        t->rchild=NULL;p->lchild=NULL;

                        q->parent=t;p->parent=q;

                        q->lchild=t;

                        q->parent=t->parent;

                        if(!q->parent){

                                bt->root=q;

                        }else{

                            if(q->parent->rchild){

                                if(q->parent->rchild==t) q->parent->rchild=q;

                            }else{

                                if(p->parent->lchild==t) q->parent->lchild=q;

                            }

                        }

                        t->parent=q;

                    }

                   

                }

                bt->len++;

                return 1;

            }

           

        }

        else{

            n--;

            printf("%d已存在",a);

            return 0;

        }

    }

   

    return 1;

}

//求左右树高

int getTHeight(TreeB *l,int h){

if(l){

    if(l->lchild && l->rchild){

        h++;

        getTHeight(l->lchild,h);

        getTHeight(l->rchild,h);

    }

    else if(l->lchild || l->rchild){

        TreeB *p;

        p=l->lchild?l->lchild:l->rchild;

        getTHeight(p,h+1);

    }else{

        return h;

    }

}  

}

//中序遍历

int forZ_sort(TreeB *t){

    if(t){

        forZ_sort(t->lchild);

        printf(" %d ",t->data);

        forZ_sort(t->rchild);

    }

}

//层次遍历树

int forC_sortTree(BTree *bt){

    TQuee tq;TreeB *t;

    init_TQuee(&tq);

    push_Quee(&tq,bt->root);

    while(tq.front!=tq.behind){

        t=pop_Quee(&tq);

        if(t->parent) printf(" 父节点为 %d ",t->parent->data);

        printf("该节点为 %d \n",t->data);

        if(t->lchild) push_Quee(&tq,t->lchild);

        if(t->rchild) push_Quee(&tq,t->rchild);

    }

}

 使用

         

int seach_B(int a[],int n){

    BTree bt;

    init_Btree(&bt);

    for(int i=0;i<n;i++){

        insert_SortTree(&bt,a[i]);

    }

    forC_sortTree(&bt);

    printf("\n");

    forZ_sort(bt.root);

}   

  • 9
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值