AVL平衡二叉搜索树

原文:

维基百科AVL树

《AVL平衡二叉搜索树》

 解决一道面试题目:

假设有一个数组,里面的数字没有排序,请找出乱序的对数。

题目在这里:http://blog.csdn.net/lileiyang12/article/details/18897521

#include<stdio.h>
#include<stdlib.h> 
#define Max				1000//数组长度

///平衡系数
#define LeftHigher		1	//左子树高
#define EqualHigher		0	//左右子树高度一样
#define RigthHigher		-1	//右子树高

struct _AVLNode				//AVL树的节点定义
{
	int data;
	int balance;			//平衡系数
	int count;				//当有重复值的时候,再此记录次数
	_AVLNode * lchild;
	_AVLNode * rchild;
};
typedef struct _AVLNode* AVLNode;

void LeftRotate(AVLNode & root)
{
	AVLNode rchild = root->rchild;
	root->rchild = rchild->lchild;
	rchild->lchild = root;
	root = rchild;
}
void RightRotate(AVLNode & root)
{
	AVLNode lchild = root->lchild;
	root->lchild = lchild->rchild;
	lchild->rchild = root;
	root = lchild;
}
void LL_LR_Balance(AVLNode & root)
{
	AVLNode lchild = root->lchild;
	switch(lchild->balance)
	{
		case LeftHigher://LL型
			root->balance = EqualHigher;
			lchild->balance = EqualHigher;
			RightRotate(root);
			break;
		case RigthHigher://LR型
			AVLNode rchild = lchild->rchild;
			switch(rchild->balance)
			{
				case LeftHigher:
					lchild->balance = EqualHigher;//最终的新左子树
					root->balance = RigthHigher;//最终的新右子树
					break;
				case EqualHigher:
					lchild->balance = EqualHigher;//最终的新左子树
					root->balance = EqualHigher;//最终的新右子树
					break;
				case RigthHigher:
					lchild->balance = LeftHigher;//最终的新左子树
					root->balance = EqualHigher;//最终的新右子树
					break;
			}
			rchild->balance = EqualHigher;
			LeftRotate(lchild);
			RightRotate(root);
			break;
	}
}

void RR_RL_Balance(AVLNode & root)
{
	AVLNode rchild = root->rchild;
	switch(rchild->balance)
	{
		case RigthHigher://RR型
			root->balance = EqualHigher;
			rchild->balance = EqualHigher;
			LeftRotate(root);
			break;
		case LeftHigher://RL型
			AVLNode lchild = rchild->lchild;
			switch(lchild->balance)
			{
				case LeftHigher:
					rchild->balance = RigthHigher;//最终的新右子树
					root->balance = EqualHigher;//最终的新左子树
					break;
				case EqualHigher:
					rchild->balance = EqualHigher;//最终的新左子树
					root->balance = EqualHigher;//最终的新右子树
					break;
				case RigthHigher:
					rchild->balance = EqualHigher;//最终的新左子树
					root->balance = LeftHigher;//最终的新右子树
					break;
			}
			lchild->balance = EqualHigher;
			RightRotate(rchild);
			LeftRotate(root);
			break;
	}
}

//在root树中插入数值为data的节点,返回false表示数值已经存在,true表示插入成功
//当高度增加则taller 为true,否则为false
bool Insert(AVLNode & root,int data,bool &taller)
{
	if(root == NULL)
	{
		root = (AVLNode)malloc(sizeof(struct _AVLNode));
		root->data		= data;
		root->balance	= EqualHigher;
		root->lchild	= NULL;
		root->rchild	= NULL;
		root->count		= 1;
		taller			= true;
		return true;
	}
	if(data == root->data )//已经存在了,不添加
	{
		root->count ++;
		taller = false;
		return false;
	}
	else if(data < root->data )//添加到左子树
	{
		if(Insert(root->lchild,data,taller))//成功插入到左子树里边了
		{
			if(taller)//左子树高度增加了
			{
				switch(root->balance)
				{
					case LeftHigher://根节点已经是左边深度高于右边,子节点又导致左深度增加到2,也就变成了LL或者LR类型,需要调节平衡,,调解后的平衡度为平衡0
						LL_LR_Balance(root);
						taller = false;
						break;
					case EqualHigher://根节点平衡,左子树高度增加,则平衡度为左高到1,不需要调节平衡
						root->balance = LeftHigher;
						taller = true;
						break;
					case RigthHigher://根节点是右变深度高于左边,左子树导致左深度增加,两边正好平衡,总高度没增加,不需要调节平衡
						root->balance = EqualHigher;
						taller = false;
						break;
					default:
						break;
				}
			}
		}
		else
		{
			return false;
		}
	} 
	else if(data > root->data )//添加到右子树
	{
		if(Insert(root->rchild,data,taller))//成功插入到右子树里边了
		{
			if(taller)//右子树高度增加了
			{
				switch(root->balance)
				{
					case LeftHigher://根节点是左边深度高于右边,子节点导致右深度增加1,两边正好平衡,总高度没增加,不需要调节平衡
						root->balance = EqualHigher;
						taller = false;
						break;
					case EqualHigher://根节点平衡,右子树高度增加1,则平衡度为右高为1,不需要调节平衡
						root->balance = RigthHigher;
						taller = true;
						break;
					case RigthHigher://根节点是右变深度高于左边,子节点又导致右深度增加到2,也就变成了RR或者RL类型,需要调节平衡,调解后的平衡度为平衡0
						RR_RL_Balance(root);
						taller = false;
						break;
				}
			}
		}
		else
		{
			return 0;
		}
	}
	return true;
}

void DFSPrint(AVLNode &root,int data)//中序遍历打印
{
	if(root == NULL)
		return;
	if(root->lchild != NULL)
		DFSPrint(root->lchild,data);

	printf("(%d,%d)\n",data,root->data);

	if(root->rchild != NULL)
		DFSPrint(root->rchild,data);
}
bool Print(AVLNode &root,int data,int length)
{
	if (root ==NULL) 
	{
		return false;
	}
	if (root->data == data) 
	{
		return true;
	}
	else if (root->data > data) 
	{
		Print(root->lchild,data,length);
	}
	else if (root->data < data) 
	{
		printf("(%d,%d)\n",data,root->data);
		DFSPrint(root->lchild,data);
		Print(root->rchild,data,length);
	}
	return true;
}
void deleteAVLNode(AVLNode & root) 
{
	if (NULL == root) 
	{
		return ;
	}
	deleteAVLNode(root->lchild);
	deleteAVLNode(root->rchild);
	free(root);
}

void Sove(AVLNode &root,int *numbers,int length)
{
	int i;
	bool taller = false;
	for(i = length-1 ; i >= 0 ; i --)
	{
		Print(root,*(numbers+i),length);
		Insert(root,*(numbers+i),taller);
	}
}
/*
输入样例:
5
1 2 5 4 3
5
1 1 1 1 1
5
1 2 3 4 5
5
5 4 3 2 1
*/
int main()
{
	int numbers[Max];
	
	AVLNode root = NULL;

	while(1)
	{
		root = NULL;
		int length , i;

		scanf("%d",&length);//数组长度
		for(i = 0 ; i < length ; i ++)//一个个输入数字
		{
			scanf("%d",&numbers[i]);
		}

		Sove(root,numbers,length);

		deleteAVLNode(root);
	}
	return 0;
}

《AVL平衡二叉搜索树》

 

 AVL树的实现

 平衡二叉树的 插入 删除 查找 等功能c语言实现 数据结构

 

    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/lileiyang12/article/details/18908847
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞