• 数据结构与算法问题 AVL二叉平衡树


    AVL树是带有平衡条件的二叉查找树。

    这个平衡条件必须保持,并且它必须保证树的深度是O(logN)。



    一棵AVL树是其每一个节点的左子树和右子树的高度最多差1的二叉查找树。

    (空树的高度定义为-1)。


    在插入以后。仅仅有那些从插入点到根节点的路径上的节点的平衡可能被改变,由于仅仅有这些节点的子树可能发生变化。当我们沿着这条路径上行到根并更新平衡信息时。我们能够找到一个节点,它的新平衡破坏了AVL条件。我们将指出怎样在第一个这种节点(即最深的节点)又一次平衡这棵树,并证明,这一又一次平衡保证整个树满足AVL特性。



    让我们把必须又一次平衡的这个节点叫做a。因为随意节点最多有两个儿子,因此高度不平衡时。a点的两棵子树的高度差2。easy看出,这样的不平衡可能出如今以下四种情况中:

    1.对a的左儿子的左子树进行一次插入

    2.对a的左儿子的右子树进行一次插入

    3.对a的右儿子的左子树进行一次插入

    4.对a的右儿子的右子树进行一次插入




    第一种情况是插入发生在“外边"的情况(即左—左的情况或右—右的情况)。该情况通过对树的一次单旋转而完毕调整。另外一种情况是插入发生在”内部“的情形(即左—右的情况或右—左的情况),该情况通过略微复杂些的双旋转来处理。

    AVL树本质上还是一棵二叉搜索树,它的特点是:



    1. 本身首先是一棵二叉搜索树。

    2. 带有平衡条件:每一个结点的左右子树的高度之差的绝对值(平衡因子)最多为1


    #include <iostream>
    using namespace std;
    const int LH = 1;
    const int EH = 0;
    const int RH = -1;
    bool TRUE = 1;
    bool FALSE = 0;
    
    typedef struct BSTNode
    {
    	int key;
    	int bf;
    	BSTNode *lchild, *rchild;
    }BSTNode;
    
    //中序遍历
    void inordertree(BSTNode * &root)
    {
    	if (root)
    	{
    		inordertree(root->lchild);
    		cout << root->key<<",";
    		inordertree(root->rchild);
    	}
    }
    
    //前序遍历
    void preordertree(BSTNode * &root)
    {
    	if (root)
    	{
    		cout << root->key<<",";
    		preordertree(root->lchild);
    		preordertree(root->rchild);
    	}
    }
    //右旋
    void R_Rotate(BSTNode * &p)
    {
    	BSTNode *lc = p->lchild;
    	p->lchild = lc->rchild;
    	lc->rchild = p;
    	p = lc;
    }
    
    //左旋
    void L_Rotate(BSTNode *& p)
    {
    	BSTNode *rc = p->rchild;
    	p->rchild = rc->lchild;
    	rc->lchild = p;
    	p = rc;
    }
    
    void LeftBalance(BSTNode * &T)
    {
    	BSTNode *lc = T->lchild;
    	switch (lc->bf)
    	{
    	case LH:
    		T->bf = lc->bf = EH;
    		R_Rotate(T);
    		break;
    	case RH:
    		BSTNode *rd = lc->rchild;
    		switch (rd->bf)
    		{
    		case LH:
    			T->bf = RH;
    			lc->bf = EH;
    			break;
    		case EH:
    			T->bf = lc->bf = EH;
    			lc->bf = LH;
    			break;
    		}
    		rd->bf = EH;
    		L_Rotate(T->lchild);//先左旋
    		R_Rotate(T);
    		break;
    	}
    }
    
    void RightBalance(BSTNode *& T)
    {
    	BSTNode *rc = T->rchild;
    	switch (rc->bf)
    	{
    	case RH:
    		T->bf = rc->bf = EH;
    		L_Rotate(T);
    		break;
    	case LH:
    		BSTNode *ld = rc->lchild;
    		switch (ld->bf)
    		{
    		case RH:
    			T->bf = LH;
    			rc->bf = EH;
    			break;
    		case EH:
    			T->bf = rc->bf = EH;
    			break;
    		case LH:
    			T->bf = EH;
    			rc->bf = RH;
    			break;
    		}
    		ld->bf = EH;
    		R_Rotate(T->rchild);
    		L_Rotate(T);
    		break;
    
    	}
    }
    
    int insertAVL(BSTNode *& t, int e, bool &taller)
    {
    	if (!t)
    	{
    		t = new BSTNode;
    		t->key = e;
    		t->lchild = t->rchild = NULL;
    		t->bf = EH;
    		taller = TRUE;
    
    	}
    	else
    	{
    		if (e == t->key)
    		{
    			taller = FALSE;
    			return 0;
    		}
    		if (e < t->key)
    		{
    			if (!insertAVL(t->lchild, e,taller))
    				return 0;
    			if (taller)
    			{
    				switch (t->bf)
    				{
    				case LH:
    					LeftBalance(t);
    					taller = FALSE;
    					break;
    				case EH:
    					t->bf = LH;
    					taller = TRUE;
    					break;
    				case RH:
    					t->bf = EH;
    					taller = FALSE;
    					break;
    
    				}
    			}
    		}
    		else
    		{
    			if (!insertAVL(t->rchild, e, taller))
    				return 0;
    			if (taller)
    			{
    				switch (t->bf)
    				{
    				case RH:
    					RightBalance(t);
    					taller = FALSE;
    					break;
    				case EH:
    					t->bf = RH;
    					taller = TRUE;
    					break;
    				case LH:
    					t->bf = EH;
    					taller = FALSE;
    					break;
    				}
    			}
    		}
    	}
    	return 1;
    }
    
    BSTNode *search(BSTNode *t, int key)
    {
    	BSTNode *p = t;
    	while (p)
    	{
    		if (p->key == key)
    			return p;
    		else if (p->key < key)
    			p = p->rchild;
    		else
    			p = p->lchild;
    	}
    	return p;
    }
    
    int main()
    {
    	BSTNode *root = NULL;
    	BSTNode *r;
    	bool taller = FALSE;
    	int array[] = { 13, 24, 37, 90, 53 };
    	for (int i = 0; i < 5; i++)
    		insertAVL(root, array[i], taller);
    	cout << "inorder traverse..." << endl;
    	inordertree(root);
    	cout << endl;
    	cout << "preorder traverse..." << endl;
    	preordertree(root);
    	cout << endl;
    	cout << "search key..." << endl;
    	r = search(root, 37);
    	if (r)
    	{
    		cout << r->key << endl;
    	}
    	else
    	{
    		cout << "not find" << endl;
    	}
    	system("pause");
    	return 0;
    }
    


  • 相关阅读:
    Service的生命周期与Activity生命周期区别
    常见浏览器兼容性问题与解决方案
    ToString()格式
    通过使用 SuppressMessage属性禁止显示或忽略代码分析冲突的功能
    javascript添加预览本地图片
    包管理器控制台常用命令
    C#读取设置Cookie(转)
    MIME类型
    stark组件(2):提取公共视图函数、URL分发和设置别名
    stark组件(1):动态生成URL
  • 原文地址:https://www.cnblogs.com/jhcelue/p/6880336.html
Copyright © 2020-2023  润新知