AVL平衡二叉树

AVL平衡二叉树

  • 定义
  • 平衡因子
  • 调整类型
    • 右右型
    • 左左型
    • 右左型
    • 左右型
  • 代码

定义

  • 单个节点是AVL树
  • 左右子树高差差不大于1
  • 左右子树都是AVL树

平衡因子

  • 左子树高度减去右子树高度
  • 如果平衡因子绝对值超过1,就必须调整。

调整类型

  • 找到引起失衡的节点
  • 计算平衡因子

右右型

  • 平衡因子为负则是右X型
  • 失衡结点右孩子的平衡因子为负则是右右型
  • 调整方法是整体左旋,与左左型调整类似

左左型

  • 失衡结点的平衡因子为正则是左X型
  • 失衡结点左孩子的平衡因子为正则是左左型
  • 调整方法是整体右旋,失衡点左孩子的右孩子改挂到右结点
失衡
插入
R
  • 调整后
插入
失衡
R

右左型

  • 平衡因子为负则是右X型
  • 因插入左孩子引起结点的失衡,则为右左型
  • 调整方法,先右旋再左旋

左右型

  • 平衡因子为负则是右X型
  • 因插入右孩子引起结点的失衡,则为右左型
  • 失衡节点的右孩子的平衡因子为负
  • 调整方法,先右旋再左旋
3
1
C
D
2
L
R
  • 调整后 先局部左旋,再整体右旋
2
1
3
D
L
R
C

代码

#include 
#include 
using namespace std;
struct AVLTree{
	int data;
	AVLTree * left;
	AVLTree * right; 
	AVLTree(int x){
		data = x;
		left=right=NULL;
	}
	AVLTree * add(AVLTree *p){
		if(p->data < data)
			left=left?left->add(p):p;
		else
			right=right?right->add(p):p;
		return adj();
	}
	void in_order(){
		if(left) left->in_order();
		cout<<data<<" ";
		if(right) right->in_order();
	}
	int h(){
		int a=left?left->h():0;
		int b=right?right->h():0;
		return max(a,b)+1;
	}
	int balance(){
		int a=left?left->h():0;
		int b=right?right->h():0; 
		return a-b;
	}
	AVLTree * adj(){
		if(abs(balance())<2) return this;
		if(balance()>0){
			if(left->balance()>0){
				AVLTree * r=left;
				left=r->right;
				r->right=this;
				return r;
			}
			else{
				AVLTree * r=left->right;
				left->right=r->left;
				r->left=left;
				left=r->right;
				r->right=this;
				return r;
			}
		}
		else{
			if(right->balance()<0){
				AVLTree * r=right;
				right=r->left;
				r->left=this;
				return r;
			}
			else{
				AVLTree* r=right->left;
				right->left=r->right;
				r->right=right;
				right=r->left;
				r->left=this;
				return r;
			}
			}
	}
}; 

int main(){
	int data[]={10,8,9,6,7,5,4,3,2,1};
	AVLTree * r=new AVLTree(data[0]);
	for(int i=1;i<sizeof(data)/sizeof(int);++i)
		r=r->add(new AVLTree(data[i]));
	r->in_order();
	cout<<endl;
	cout<<r->h()<<endl;
	return 0;
}

你可能感兴趣的:(C++,算法,数据结构,平衡二叉树)