您的位置:首页 > 编程语言

算法基础(七):二叉排序树基本操作-插入、删除(附源代码加注释)

2014-03-11 21:01 423 查看
#include"stdafx.h"
#include"Basic_Symbol.h"

#define MaxSize 100
typedef int KeyType;		//定义关键字类型
typedef char InfoType;
typedef struct node			//定义结点类型
{
KeyType key;			//关键字项
InfoType data;			//数据域
struct node
*lchild,
*rchild;			//左右孩子指针
}BSTNode;
//全局变量
KeyType predt = -32767;				//保存中序节点前驱的值
int path[MaxSize];					//全局变量,用于存放路径

void DispBST(BSTNode *b);	//函数声明

int InsertBST(BSTNode *&p, KeyType k)			//P为根节点,插入关键字为K的结点
{
if( p == NULL)								//如果原树为空,则操作
{
p = (BSTNode *)malloc(sizeof(BSTNode)); //分配空间
p->key = k;
p->lchild = p->rchild = NULL;			//左右孩子初值为空
return 1;
}
else if(k == p->key)						//如果等于,则return,因为二叉排序树里面不会有两个相等的数字
return 0;
else if(k < p->key)							//如果小于,则放左边,要深刻理解递归,代码便写的自然
return InsertBST(p->lchild,k);
else return InsertBST(p->rchild,k);			//大于,放右边,满足二叉排序树的特点
}

BSTNode *CreatBST(KeyType A[],int n)			//利用数组A中的元素作为关键字来构造二叉树,n为要建立的结点个数,应小于数组长度
{
BSTNode *bt = NULL;
int i = 0;
while(i< n)									//循环加递归构造二叉排序树
if(InsertBST(bt,A[i]) == 1)
{
printf("\nthe number %d step:",i+1,A[i]);
DispBST(bt);
i++;
}
return bt;									//返回根指针
}

void Delete1(BSTNode *p,BSTNode *&r)			//当被删除结点p有左右子树时的删除过程
{
BSTNode *q;
if(r->rchild != NULL)		//如果右孩子不为空
{
Delete1(p,r->rchild);	//递归找到最右下节点,为什么要找最右下节点了,因为最右下节点是这棵树中最大的。
}
else						//找到了最右下
{
p->key = r->key;		//将r的关键字赋值给p,这是必须的,只有r的关键字(x)可以来胜任..x是左边的树中最大的但是小于p->key,更小于p的右子树。
q = r;
r = r->lchild;			//r的值被r左孩子代替
free(q);				//释放空间
}
}
void Delete( BSTNode *&p)		//从二叉排序树中删除*p结点,这是在已经找到了要删除的节点时调用的,在DeleteBST中被调用
{
BSTNode *q;
if(p->rchild == NULL)		//没有右子树的情况
{
q = p;
p = p->lchild;			//p指向的内存空间被释放,显然此时p退居到左孩子位置,哈哈!画个图图看看更清晰哈
free(q);
}
else if(p->lchild == NULL)	//没有左子树,同样的道理..
{
q = p;
p = p->rchild;
free(q);
}
else Delete1(p,p->lchild);	//左右都有的话,调用DELETE1函数来处理该情况
}
int DeleteBST(BSTNode *&bt,KeyType k)		//在bt中删除关键字为k的结点
{
if(bt == NULL)
return 0;							//空树,删除失败
else
{
if(k < bt->key)
return DeleteBST(bt->lchild,k);
else if(k>bt->key)
return DeleteBST(bt->rchild,k);
else
{
Delete(bt);
return 1;
}
}
}
void SearchBST1(BSTNode *bt,KeyType k,KeyType path[],int i)		//以非递归方式输出路径
{
int j;
if(bt == NULL)
return;
else if(k == bt->key)						//找到了
{
path[i+1] = bt->key;					//将节点的值保存在路径中
for(j = 0;j<=i+1;j++)
printf("%3d",path[j]);				//输出
printf("\n");
}
else										//没找到
{
path[i + 1] = bt->key;					//将节点的值保存在路径中,下面更具情况继续找
if(k < bt->key)							//如果k小于当前值
SearchBST1(bt->lchild,k,path,i+1);  //则进入左子树找,这是根据二叉排序树的特点来的
else
SearchBST1(bt->rchild,k,path,i+1);	//大的话。进入右边找。其实找,还是在递归,只是把路径保存在一个可爱的数组中而已
}
}
int SearchBST2(BSTNode *bt,KeyType k)			//递归输出路径,就要简单的多了,但是理解不是很容易,递归太重要了,对吧!
{
if(bt == NULL)
return 0;
else if(k == bt->key)
{
printf("%3d",bt->key);
return 1;
}
else if(k < bt->key)
SearchBST2(bt->lchild,k);
else SearchBST2(bt->rchild,k);
printf("%3d",bt->key);
}
void DispBST(BSTNode *bt)								//括号表示法输出二叉排序树
{
if(bt != NULL)
{
printf("%d",bt->key);							//输出根节点的值
if(bt->lchild != NULL || bt->rchild != NULL)	//如果左右孩子不为空,输出他们的key值
{
printf("(");
DispBST(bt->lchild);
if(bt->rchild != NULL)
printf(",");
DispBST(bt->rchild);
printf(")");
}
}
}

int JudgeBST(BSTNode *bt)				//判断是否是二叉排序树
{
int b1,b2;
if(bt == NULL)						//空则返回
return 1;
else
{
b1 = JudgeBST(bt->lchild);		//递归得到最左下的节点
if(b1 == 0 || predt >= bt->key) //如果左边的值比其父节点的key大,则不是二叉排序树,返回0,如果父节点的key大于右边的key,则返回0
return 0;
predt = bt->key;				//依次得到key值,注意这个语句的位置,pre的得到是按照左到右的顺序
printf("\npredt = %d",predt);
b2 = JudgeBST(bt->rchild);		//判断右边
return b2;
}
}
/*
总结:我觉得数据结构,最重要的是它的思想,真的是非常的精妙。
像《树》这章,树的层次结构首先我们要清晰,然后就是深刻理解递归的思想,这又牵扯到栈的知识。

*/
void main()
{
BSTNode *bt;
KeyType k = 6;					//后面要寻找带这个关键字的节点
int n = 10;						//数组元素个数
int a[] = {4,9,0,1,8,6,3,5,2,7};
printf("create a BST Tree:\n");
bt = CreatBST(a,n);
printf("BST:\n");
DispBST(bt);
printf("\n");
printf("bt%s\n",(JudgeBST(bt)?"yes,it is a bst":"no,it is not a bst"));
printf("\n");
printf("\nsearch the keyword(di gui) : %d",k);
SearchBST1(bt,k,path, -1);
printf("\nsearch the keyword(not di gui) : %d",k);
printf("\ndelete...");
printf("\nthe origin BST:");
DispBST(bt);
printf("\n delete the node 4..");
DeleteBST(bt,4);
DispBST(bt);
printf("\n delete the node 5..");
DeleteBST(bt,5);
DispBST(bt);
printf("\n");
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 二叉树
相关文章推荐