平衡思路
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);
}