我是靠谱客的博主 优雅衬衫,最近开发中收集的这篇文章主要介绍平衡二叉树的 插入 删除 查找 等功能c语言实现 数据结构,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述



在很久很久以前至昨天,一直不理解左旋右旋的概念,只是死记硬背下了旋转的模式。 today 忽然明白了什么叫左旋、右旋。 today is 2015.9.12!周末在公司学习的菜鸟又明白了一个知识点,可喜可贺啊! ps越来越不喜欢csdn了, 谁能告诉我如何去掉最上面这行东东!


PS 每次编辑这篇文章,所有除代码之外的东西都变成了乱码 图片也变成了url 真奇葩! csdn 真的是要别了!   我已经被折磨投了!       中间修改了几次  搞的我想吐 真的不想再用csdn了 。。。。。。


图中的A B C 可能代表多个节点




当A B C 代表多个节点时:




其它几种情况的旋转 可以参考 http://blog.csdn.net/vesper305/article/details/13614403 这篇真的很好那!



有朋友反应下面代码中删除可能有问题, 很久以前的代码  没时间整理了,见谅。

#include<time.h>
#include<stdio.h>  
#include<stdlib.h> 
//左子树比右子树高一
#define LH 1
//左子树和右子树一样高
#define EH 0
//左子树比右子树低一
#define RH -1
#define EQ(a,b) ((a) == (b))
#define LT(a,b) ((a) < (b))
#define LQ(a,b)((a) <= (b))

typedef struct BSTNode
{
	int data;
	int bf;
	BSTNode * lchild;
	BSTNode * rchild;
}BSTNode;
typedef BSTNode * BSTree;

//	左旋
void leftRotate(BSTree & root) 
{
	BSTree rc = root->rchild;
	root->rchild = rc->lchild;
	rc->lchild = root;
	root = rc;
}
//	右旋
void rightRotate(BSTree & root) 
{
	BSTree lc = root->lchild;
	root->lchild = lc->rchild;
	lc->rchild = root;
	root = lc;
}
//	对二叉树root进行左平衡处理(LL型和LR型)
void leftBalance(BSTree & root) 
{
	BSTree lc = root->lchild;
	switch (lc->bf) 
	{
		//LL型的只需要进行右旋操作
	case LH:
		//右旋之后根和左子树都的平衡的
		root->bf = EH;
		lc->bf = EH;
		//右旋操作
		rightRotate(root);
		break;
		//LR型的需要进行左旋操作,然后右旋操作
	case RH:
		BSTree rc = lc->rchild;
		switch (rc->bf) 
		{
		case LH:
			root->bf = RH;
			lc->bf = EH;
			break;
		case EH:
			root->bf = EH;
			lc->bf = EH;
			break;
		case RH:
			root->bf = EH;
			lc->bf = LH;
			break;
		}
		rc->bf = EH;
		leftRotate(root->lchild);
		rightRotate(root);
		break;
	}
}
//	功能:对二叉树root进行左平衡处理(RR型和RL型)
void rightBalance(BSTree & root) 
{
	BSTree rc = root->rchild;
	switch (rc->bf) 
	{
		//RR型只需要做左旋操作
	case RH:
		root->bf = EH;
		rc->bf = EH;
		//左旋操作
		leftRotate(root);
		break;
		//RL型需要先做右旋操作,然后做左旋操作
	case LH:
		BSTree lc = rc->lchild;
		switch (lc->bf) 
		{
		case LH:
			root->bf = EH;
			rc->bf = RH;
			break;
		case EH:
			root->bf = EH;
			rc->bf = EH;
			break;
		case RH:
			root->bf = LH;
			rc->bf = EH;
			break;
		}
		lc->bf = EH;
		rightRotate(root->rchild);
		leftRotate(root);
		break;
	}
}
//	功能:把元素data插入平衡二叉树root中
bool insert(BSTree & root, int data, bool & taller) 
{
	if (NULL == root) 
	{
		root = (BSTree)malloc(sizeof(BSTNode));
		root->rchild = NULL;
		root->lchild = NULL;
		root->data = data;
		root->bf = EH;
		taller = true;
	}
	else
	{
		//该元素已经在平衡二叉树中存在了
		if (data == root->data) 
		{
			taller = false;
			return false;
		}
		//插入左子树
		else if (data < root->data) 
		{
			if (!insert(root->lchild, data, taller)) 
			{
				return false;
			}
			//插入成功,并且树变高了
			if (taller) 
			{
				switch (root->bf) 
				{
				case LH:
					leftBalance(root);
					//平衡二叉树做完左平衡操作后
					//树高没有变化,故taller = false
					taller = false;
					break;
				case EH:
					root->bf = LH;
					//原来是平衡的故插入一个元素后
					//树高必然变高
					taller = true;
					break;
				case RH:
					root->bf = EH;
					//原来是右子树比左子树高,但是当向左子树中
					//插入一个元素的时候,树变平衡了,故taller = false
					taller = false;
					break;
				default:
					break;
				}
			}
		}
		//插入右子树
		else 
		{
			if (!insert(root->rchild, data, taller)) 
			{
				return 0;
			}
			if (taller) 
			{
				switch (root->bf) 
				{
				case LH:
					root->bf = EH;
					taller = false;
					break;
				case EH:
					root->bf = RH;
					taller = true;
					break;
				case RH:
					rightBalance(root);
					taller = false;
					break;
				}
			}
		}
	}
	return true;
}
//   在平衡二叉树中查找int节点
int * search(BSTree & root, int data) 
{
	if (root ==NULL) 
	{
		return NULL;
	}
	
	if (root->data == data) 
	{
		return &root->data;
	}
	else if (data < root->data) 
	{
		return search(root->lchild, data);
	} 
	else 
	{
		return search(root->rchild, data);
	}
}
//	功能:输出平衡二叉树中的所有的元素(小->大,中序遍历)
void print(BSTree & root)
{
	if (NULL == root) 
	{
		return ;
	}
	
	print(root->lchild);
	printf("%d ",root->data);
	print(root->rchild);
}
//	功能:释放平衡二叉树的空间
void clear(BSTree & root) 
{
	if (NULL == root) 
	{
		return ;
	}
	clear(root->lchild);
	clear(root->rchild);
	free(root);
}
int DeleteAVL(BSTree &T, int key, bool &shorter){
	if (!T)
	{//No such key
		shorter = false;
		return 0;
	}
	else
	{
		if (EQ(key, T->data))	//找到了需要删除的结点
		{
			//如果该结点的lchild 和
			//rchild 至少有一个为NULL
			//则大功告成,否则请参照
			//下方解释
			BSTree q = T;
			if (!T->lchild)//如果该结点的lchild 为NULL
			{
				q = T;
				T = T->rchild;
				free(q);
				shorter = true;
				return 1;
			}
			else if (!T->rchild){//如果该结点的rchild 为 NULL
				q = T;
				T = T->lchild;//如果不是&(引用)的强大功能,这句话是没有意义的
				free(q);
				shorter = true;
				return 1;
			}
			else {
				//删除一个左右孩子都不为空的结点
				//使该结点的直接前驱p的data替换该结点的data
				//然后改变key=p.data
				BSTree s = T->lchild;
				while (s->rchild)
					s = s->rchild;
				T->data = s->data;
				key = s->data;//Now, delete the vertice whose data was the new key
			}
		}
		if (LQ(key, T->data)){//这里与InsertAVL不同
			if (!DeleteAVL(T->lchild, key, shorter)) return 0;
			if (shorter){
				switch(T->bf){
				case LH:T->bf = EH; shorter = true;break;
				case EH:T->bf = RH;shorter = false;break;
				case RH:rightBalance(T); 
					if (T->rchild->bf == EH)
						shorter = false;
					else 
						shorter = true;break;
				}
			}
		}
		else{
			if (!DeleteAVL(T->rchild, key, shorter)) return 0;
			if (shorter){
				switch(T->bf){
				case LH:leftBalance(T);
					if (T->lchild->bf == EH)
						shorter = false;
					else 
						shorter = true;break;
				case EH:T->bf = LH; shorter = false;break;
				case RH:T->bf = EH;shorter = true;break;
				}
			}
		}
	}
	return 1;
}//Delete
void menu()  
{  
	printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙ ⊙☆⊙    主菜单     ⊙☆⊙ ⊙☆⊙ ⊙☆⊙ ⊙☆⊙n");  
	printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 1:连续插入数据 输入0结束插入⊙☆⊙ ⊙☆⊙ ⊙☆⊙n");  
	printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 2:查找数据                  ⊙☆⊙ ⊙☆⊙ ⊙☆⊙n");  
	printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 3删除特定数据               ⊙☆⊙ ⊙☆⊙ ⊙☆⊙n");  
	printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 4输出当前结果                   ⊙☆⊙ ⊙☆⊙ ⊙☆⊙n"); 
    printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 5结束程序                   ⊙☆⊙ ⊙☆⊙ ⊙☆⊙n");
}  
int main()
{
	BSTree root = NULL;
	int num,n;
	bool taller = false,shorter;
	system("color 2e");  
	menu();
	while(1)  
	{  
		scanf("%d",&num); 
		//if(num==5) break;
		switch (num)  
		{  
		case 1:
			system("cls");
			printf("请插入数据 ,输入0结束插入n");
			while(scanf("%d",&n))
			{
				if(n==0) break;
				else insert(root,n,taller);
			}
			system("cls");
			menu();
			break;
		case 2: 
			system("cls");
			printf("请输入要查询的数n");
			scanf("%d",&n);
			int *p;
			p=search(root,n);
			if (p==NULL) 
			{
				printf("对不起 没有找到 %d!n",n);
			}
			else 
			{
				printf("恭喜你 数据中存在 %d!n",n);
			}
			menu();
			break;  
		case 3: 
			system("cls");
			printf("请输入要删除的数据n");
			scanf("%d",&n);
			DeleteAVL(root,n,shorter);
			menu();
			break;
		case 4:
			system("cls");
			print(root); 
			printf("输入0进入主菜单n");
			scanf("%d",&n);
			if(!n)
			  menu();
			break;
		case 5:
			clear(root);
			return 0;		
		}
	}
	return 0;
}



参考了 ACb0y的代码


最后

以上就是优雅衬衫为你收集整理的平衡二叉树的 插入 删除 查找 等功能c语言实现 数据结构的全部内容,希望文章能够帮你解决平衡二叉树的 插入 删除 查找 等功能c语言实现 数据结构所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(33)

评论列表共有 0 条评论

立即
投稿
返回
顶部