avl树



AVL树  左子树和右子树之间差的绝对值不超过一 ,同时他们的左右子树也一样
AVL树的左子上的值比根的值小,根的值比右子的值小
如图为一个 AVL树

AVL树的结构体定义如下

typedef int KeyType;
typedef struct AVLNode
{
 AVLNode *leftchild;
 AVLNode *parent;
 AVLNode *rightchild;
 int balance;
 KeyType key;
}AVLNode;
typedef struct
{
 AVLNode *head; // head not root;
 int cursize;
}AVLTree;


该树结构中有左子,右子,双亲节点 同时有平衡和关键值该树有头节点

头节点为这棵树根节点的双亲节点,同时根节点也为头节点的双亲节点现在为树添加关键值

关键值为右子高度减去左子高度


为该树添加一个值,导致这个树不平衡

为了让这颗树平衡,我们开始左旋这棵树

可以看到左旋就是让这棵树根节点下移,让原先不平衡节点的右子的左子为不平衡节点的右子,不平衡节点作为其右子的左子

代码如下      图中45为不平衡节点  78为新节点

void RotateLeft(AVLNode *head,AVLNode *ptr)
{
	AVLNode *newroot = ptr->rightchild;//新节点为不平衡节点的右子
	newroot->parent = ptr->parent; //新节点的双亲节点为不平衡节点的双亲
	ptr->rightchild = newroot->leftchild;//不平衡节点的右子为新节点的左子
	if(newroot->leftchild != NULL)
	{
		newroot->leftchild->parent = ptr; //新节点左子的双亲节点为不平衡节点 
	}
	newroot->leftchild = ptr;//新节点左子为不平衡节点 
	if(head->parent == ptr) // 如果头节点的双亲节点为不平衡节点
	{
		head->parent = newroot;//头节点的双亲节点
	}
	else
	{
		if(ptr->parent->rightchild == ptr)//如果不平衡节点双亲节点的右子不平衡节点
		{
			ptr->parent->rightchild = newroot;//不平衡节点双亲节点的右子为新节点
		}
		else
		{
			ptr->parent->leftchild = newroot;
		}
	}
	ptr->parent = newroot;// 3
}

右旋类似

void RotateRight(AVLNode *head,AVLNode *ptr)
{
	AVLNode * newroot = ptr->leftchild;
	newroot->parent = ptr->parent; //1
	ptr->leftchild = newroot->rightchild;
	if(newroot->rightchild != NULL)
	{
		newroot->rightchild->parent = ptr; //2
	}
	newroot->rightchild = ptr;
	if(head->parent == ptr) //root
	{
		head->parent = newroot;
	}
	else
	{
		if(ptr->parent->leftchild == ptr)
		{
			ptr->parent->leftchild = newroot;
		}
		else
		{
			ptr->parent->rightchild = newroot;
		}
	}
	ptr->parent = newroot;//3
}

如果头节点的双亲节点为原不平衡节点,让新节点为头节点  原节点是左,则新节点是左,是右则右

二叉树平衡后该关键值操作代码如下

void LeftBalance(AVLNode *head,AVLNode *ptr)
{
	AVLNode *leftsub = ptr->leftchild, *rightsub = NULL;
	switch(leftsub->balance)
	{
	case 0: cout<<"Left already balance "<<endl; break;
	case -1:
		ptr->balance = 0;
		leftsub->balance = 0;
		RotateRight(head,ptr);
		break;
	case 1:
		rightsub = leftsub->rightchild;
		switch(rightsub->balance)
		{
		case 1:
			ptr->balance = 0;
			leftsub->balance = -1;
			break;
		case -1:
			ptr->balance = 1;
			leftsub->balance = 0;
			break;
		case 0:
			ptr->balance = 0;
			leftsub->balance = 0;
			break
		}
		rightsub->balance = 0;
		RotateLeft(head,leftsub);
		RotateRight(head,ptr);
		break;
	}
}

void RightBalance(AVLNode *head,AVLNode *ptr)
{
	AVLNode *rightsub = ptr->rightchild, *leftsub = NULL;
	switch(rightsub->balance)
	{
	case 0: break;
	case 1: 
		RotateLeft(head,ptr);
		break;
	case -1:
		leftsub = rightsub->leftchild;

		break;
	}
}

其它代码

AVLNode * Buynode()
{
	AVLNode *s = (AVLNode*)malloc(sizeof(AVLNode));
	if(NULL == s) exit(1);
	memset(s,0,sizeof(AVLNode));
	return s;
}
void Freenode(AVLNode *p)
{
	free(p);
}

void Init_Tree(AVLTree *ptree)
{
	if(ptree == NULL) exit(1);
	AVLNode *s = Buynode();
	s->leftchild = NULL;
	s->rightchild = NULL;
	s->parent = NULL;
	s->balance = 0;
	ptree->head = s;
	ptree->cursize = 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值