首页 > 其他 > 详细

AVL树

时间:2014-07-03 13:49:57      阅读:309      评论:0      收藏:0      [点我收藏+]

bubuko.com,布布扣

a) 可以借助第3章的3.25式 Fh=ψ^h/√5  (ψ<1.618) 来求得h的高度。

b,c,d完全可以查看下面的程序得出结论。我这个程序是在书中所给二叉查找树插入函数和红黑树旋转原函数基础之上稍加修改得到的结果。BLANCE函数是查看维基和百度百科得到的。代码如下:

//AVL树
#include <iostream>
using namespace std;
#define LEN sizeof(struct AVLTree)
struct AVLTree
{
	struct AVLTree*left;
	struct AVLTree*right;
	struct AVLTree*parent;
	int key;
	int high;
};
struct AVLTree*root=NULL;
void InOderTraverse(struct AVLTree *p);
int Max(int a, int b)
{
    return (a > b ? a : b);
}
int Height(struct AVLTree* p)
{
    if (NULL == p)
        return -1;
    return p->high;
}
struct AVLTree*LEFT_ROTATE(struct AVLTree*x)
{//左旋转:分三个步骤①②③来叙述旋转代码的。
	struct AVLTree*y=x->right;//设置y结点。
	x->right=y->left;//本行代码以及下面的if结构表达的是“y的左孩子成为x的右孩子”。①
	if(y->left!=NULL)
	{
		y->left->parent=x;
	}
	y->parent=x->parent;//本行代码以及下面的if-else结构表达的过程是“y成为该子树新的根”。②
	if(x->parent==NULL)
	{
		root=y;
	}
	else if(x==x->parent->left)
	{
		x->parent->left=y;
	}
	else x->parent->right=y;
	y->left=x;//本行代码以及下面一行都表达了“x成为y的左孩子”。③
	x->parent=y;
	// 结点的位置变了, 要更新结点的高度值
    x->high = Max(Height(x->left), Height(x->right)) + 1;
    y->high = Max(Height(y->left), x->high) + 1;
	return y;
}
struct AVLTree* RIGHT_ROTATE(struct AVLTree*x)
{//右旋转:分三个步骤①②③来叙述旋转代码的。
	struct AVLTree*y=x->left;//设置y结点。
	x->left=y->right;//本行代码以及下面的if结构表达的是“y的左孩子成为x的右孩子”。①
	if(y->right!=NULL)
	{
		y->right->parent=x;
	}
	y->parent=x->parent;//本行代码以及下面的if-else结构表达的过程是“y成为该子树新的根”。②
	if(x->parent==NULL)
	{
		root=y;
	}
	else if(x==x->parent->right)
	{
		x->parent->right=y;
	}
	else x->parent->left=y;
	y->right=x;//本行代码以及下面一行都表达了“x成为y的左孩子”。③
	x->parent=y;
	// 结点的位置变了, 要更新结点的高度值
    x->high = Max(Height(x->left), Height(x->right)) + 1;
    y->high = Max(Height(y->right), x->high) + 1;
	return y;
}
struct AVLTree* Double_RIGHT_ROTATE(struct AVLTree*x)
{
    x->left = LEFT_ROTATE(x->left);
    return RIGHT_ROTATE(x);
}
struct AVLTree* Double_LEFT_ROTATE(struct AVLTree*x)
{
    x->right = RIGHT_ROTATE(x->right);
    return LEFT_ROTATE(x);
}
void BLANCE(int key, struct AVLTree*p)
{
   if (key < p->key) 
   {
	   if (Height(p->left) - Height(p->right) == 2)    // AVL树不平衡
	   {
		   if (key < p->left->key)
		   {
			   p = RIGHT_ROTATE(p);// 插入到了左子树左边, 做单旋转
		   }
		   else 
		   {
			   p = Double_RIGHT_ROTATE(p);// 插入到了左子树右边, 做双旋转
		   }
        }
   }
   else
   {
	   if (Height(p->right) - Height(p->left) == 2)    // AVL树不平衡
	   {
		   if (key > p->right->key)
		   {
			   p = LEFT_ROTATE(p);// 插入到了右子树右边, 做单旋转
		   }
		   else 
		   {
			   p = Double_LEFT_ROTATE(p);// 插入到了右子树左边, 做双旋转
		   }
        }
   }
}
//非递归的AVL插入函数
struct AVLTree* AVLTree_INSERT(struct AVLTree*z,struct AVLTree*&root)
{
	struct AVLTree*y=NULL;
	struct AVLTree*x=root;
	while (x)
	{
		y=x;
		if (z->key<x->key)
			x=x->left;
		else x=x->right;
	}
	z->parent=y;
	if (y==NULL)
	{
		root=z;
	} 
	else if(z->key<y->key)
	{
		y->left=z;
	}
	else y->right=z;  
    z->left=z->right=NULL;
	z->high=0;
	struct AVLTree*p=z;
	while (p)//对从新插入结点回溯到根结点这条路径上的所有结点都进行平衡和确定其高度操作
	{//迭代操作使结点不断的上移,最终达到根结点
	   BLANCE(z->key, p);//平航当前结点
       p->high = Max(Height(p->left), Height(p->right)) + 1;//当前结点的左右子树高度取较大者+1
	   p=p->parent;//向上回溯
	}
	return root;
}
//中序遍历
void InOderTraverse(struct AVLTree *p)
{
    if (p)
	{		
		InOderTraverse(p->left);
		cout<<p->key<<" "<<p->high<<" "<<endl;
		InOderTraverse(p->right);
	}
}
void main()
{
	int array[5]={2,1,3,5,4};
    for (int i=0; i <5; ++i)
    {
		struct AVLTree*z=new struct AVLTree[LEN];
		z->key=array[i];
        root=AVLTree_INSERT(z,root);
    }
    InOderTraverse(root);
}



AVL树,布布扣,bubuko.com

AVL树

原文:http://blog.csdn.net/z84616995z/article/details/36639665

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!