平衡二叉树,两边高度差的不大于1
这个每次在插入后出现不平衡,去把第一个不平衡的点调整平衡就可以。
这里面有LL,LR,RL,RR四种方式。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h> #include<iostream> #include<string.h> #include<queue> using namespace std; struct node{ int v,height; node*lchild,*rchild; }; node*newNode(int x) { node*temp=new node; temp->v=x; temp->height=1; temp->lchild=NULL; temp->rchild=NULL; return temp; } int getHeight(node*root) { if(root==NULL) return 0; else return root->height; } int getBalanceFactor(node*root) { return getHeight(root->lchild)-getHeight(root->rchild); } void updateHeight(node*root) { root->height=max(getHeight(root->lchild),getHeight(root->rchild))+1; } void search(node*root,int x) { if(root==NULL) { printf("Search failed "); return; } if(x==root->v) { printf("%d ",root->v); } else if(root->v>x) { search(root->lchild,x); } else search(root->rchild,x); } void L(node*&root) { node*temp=root->rchild; root->rchild=temp->lchild; temp->lchild=root; updateHeight(root); updateHeight(temp); root=temp; } void R(node*&root) { node*temp=root->lchild; root->lchild=temp->rchild; temp->rchild=root; updateHeight(root); updateHeight(temp); root=temp; } void insert(node*&root,int v) { if(root==NULL) { root=newNode(v); return; } if(root->v>v) { insert(root->lchild,v); updateHeight(root); if(getBalanceFactor(root)==2) { if(getBalanceFactor(root->lchild)==1) { R(root); } else { L(root->lchild); R(root); } } } else { insert(root->rchild,v); updateHeight(root); if(getBalanceFactor(root)==-2) { if(getBalanceFactor(root->rchild)==-1) { L(root); } else { R(root->rchild); L(root); } } } } node*Create(int data[],int n) { node*root=NULL; for(int i=0;i<n;i++) insert(root,data[i]); return root; } void levelOrder(node*root) { queue<node*>q; q.push(root); while(!q.empty()) { node*temp=q.front(); q.pop(); printf("%d",temp->v); printf("%d ",temp->height); if(temp->lchild!=NULL) q.push(temp->lchild); if(temp->rchild!=NULL) q.push(temp->rchild); } } int main() { node*root=NULL; int a[10]={1,2,3,4,5,6,7}; root=Create(a,4); levelOrder(root); return 0; }
左旋和右旋,判断左右的方式是看里面的root点(被旋转的参数点)是向左还是向右
所有的移动后都仍然是平衡二叉树,所以移动的最终过程,是把A>B>C的B变成新的root,在遇到折线的时候需要做两次。
注意updateHeight的时候从底层开始update,根节点就是height为1,不需要update。
getHeight函数是为了在root为NULL的时候不用在代码段里面特判不能访问root->height(getHeight别忘了下一层的max+1)
这个在每次插入以后就保证了平衡,在别的访问的时候直接调用数据就行。
在L和R的存储过程中要注意存好孩子,跟swap(a,b)原理差不多
判断好左右旋转以后执行相关操作就可以。