二叉查找树

//二叉查找树


#include "stdio.h"
#include "stdlib.h"

#define Type int

struct TreeNode;
typedef struct TreeNode *SearchTree;
typedef struct TreeNode *Position;

struct TreeNode
{
	Type Element;
	SearchTree left;
	SearchTree right;
	//bool turn; 懒惰删除域
};

SearchTree MakeEmpty(SearchTree T);
Position Find(Type X,SearchTree T);
Position FindMin(SearchTree T);
Position FindMax(SearchTree T);
SearchTree Insert(Type X,SearchTree T);
SearchTree Delete(Type X,SearchTree T);


SearchTree MakeEmpty(SearchTree T)//销毁树
{
	if(T!=NULL)
	{
		MakeEmpty(T->left);
		MakeEmpty(T->right);
		free(T);//清空T的内容
	}
	return NULL;
}

Position Find(Type X,SearchTree T)//注意,返回的是节点,并不是值!
{
	if(T==NULL)
		return NULL;
	else if(X<T->Element)
		return Find(X,T->left);//每个节点的Element大于left的Element,小于right的Element
	else if(X>T->Element)
		return Find(X,T->right);
	else//找到了那个元素
		return T;
}

Position FindMin(SearchTree T)//自顶向下查找 
{
	if(T==NULL)//此节点无儿子
		return NULL;
	else if(T->left==NULL)
		return T;
	else
		return FindMin(T->left);
}

Position FindMax(SearchTree T)//与Findmin均为递归实现,若不递归,利用If和while不断遍历左节点或右节点即可
{
	if(T==NULL)//此节点无儿子
		return NULL;
	else if(T->right==NULL)
		return T;
	else
		return FindMax(T->right);
}

SearchTree Insert(Type X,SearchTree T)//相当于creat,再不断的input同时,creat Tree;
{
	if(T==NULL)//建立一个二叉树,若无树,应先运用MakeEmpty例程
	{
		T=(SearchTree)malloc(sizeof(struct TreeNode));
		if(T==NULL)
			printf("OUT OF SPACE\n");
		else
		{
			T->Element=X;
			T->left=NULL;
			T->right=NULL;
		}
	}
	else if(X<T->Element)
	{
		T->left=Insert(X,T->left);//递归过程中不断遍历至适当的左节点。
	}
	else if(X>T->Element)
	{
		T->right=Insert(X,T->right);
	}
	//此例程并未考虑如果insert的元素已在树中。可以在下面的代码段加入适当内容以补充
	//if(X===T->Element)
	//{
	//     ;
	//}
	return T;//tree root
}

SearchTree Delete(Type X,SearchTree T)
{
	/*自己画图,如果删除的是树叶,则直接删除,不是树叶,需要考虑
	1.有一个儿子的节点.通过更改该节点的父节点的指针,指向该节点的儿子(参考链表绕过被删元素);
	2.有两个儿子的节点,用该节点的右子树最小节点代替该节点,删除右子树最小节点.
	注意:这里的删除涉及到指针的改变,和空间的释放(free).缺一不可.
	*/
	Position TmpCell;
	if(T==NULL)
		printf("You can't delete a NULL Tree\n");
	else if(X<T->Element)
		T->left=Delete(X,T->left);
	else if(X>T->Element)
		T->right=Delete(X,T->right);
	//以上两句相当于在遍历整个树以找到元素,一旦找到,执行下面的语句
	else//找到了元素
	{
		if(T->left && T->right)//if(T->left!=NULL && T->right!=NULL)
		{
			TmpCell=FindMin(T->right);//此处FindMin小题大做了,可以直接找right的left,不断遍历left.
			T->Element=TmpCell->Element;
			T->right=Delete(T->Element,T->right);//找到右子数的最小节点(it has only one children),删除它.
		}
		else//one children or leaf
		{
			TmpCell=T;
			if(T->left==NULL)
				T=T->right;
			else if(T->right==NULL)
				T=T->left;
			free(TmpCell);
			//若left,right有其一,则T被其取代,否则直接freeT(Tmpcell).
			//这是一个包含例程,它能同时处理one children和leaf的情况!
		}
	}
	return T;
}
//若采用懒惰删除,则用bool turn域给每个元素加一个标记,依据标记进行遍历,符合的输出/遍历,不符合的不输出/遍历 .


//二叉查找树只是一种结构,它并不完美,如果有一些不好的输入,会产生一些很差的二叉树(一边深一边浅)但它是树的一个基本构架.


int main()
{
	SearchTree T=NULL;
	int n;
	int i;
	for(i=0;i<5;i++)
	{
		scanf("%d",&n);
		T=Insert(n,T);
	}
	int Max;
	int Min;
	SearchTree tmp;
	tmp=FindMax(T);
	Max=tmp->Element;
	tmp=FindMin(T);
	Min=tmp->Element;
	printf("Max=%d Min=%d\n",Max,Min);
	T=Delete(Max,T);
	tmp=FindMax(T);
	Max=tmp->Element;
	printf("Max=%d Min=%d\n",Max,Min);
	return 0;
}
/*
输入输出检测
3 1 2 5 4
Max=5 Min=1
Max=4 Min=1
Press any key to continue
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值