zoukankan      html  css  js  c++  java
  • AVL树

    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);
    }

    
  • 相关阅读:
    适配器模式
    显示实现接口
    Mysql表引擎的切换
    Mysql事务隔离级别
    按照指定的格式解析字节数组
    委托和事件的简单实用
    C#压缩和解压缩字节(GZip)
    Mysql数据库批量添加数据
    常用的分页类
    保证依赖的服务已全部启动
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4290844.html
Copyright © 2011-2022 走看看