您的位置:首页 > 其它

二叉查找树

2014-03-20 16:38 148 查看
//二叉查找树

#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
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二叉树 查找树