在查找这一章,我认为静态查找都比较简单,所以就跳过了,二叉排序树以及与之相关的一些数据结构还是有一定意义的。二叉排序树:左子树小于根节点,右子树大于根节点。这个原理很简单,就上面几行几个字,实现起来代码也很简洁,使用递归调用。在节点删除的时候,到时有不同的情况,需要注意一下。
(1)若待删除节点是叶子节点,则之间删除,修改下父节点的指针就可以了。
(2)若只有左子树或右子树,直接将其子树接到待删除节点的父节点后面就可以了。
(3)若既有左子树又有右子树的,相对就麻烦一些。其中有两种方法:第一,将左子树接到其父节点上,然后将其右子树接到左子树的最右端,这是因为右子树的节点都是比左子树大的,所以将右子树接到左子树最大的位置,也就是最右端,依次也可以将右子树接到父节点上,然后将左子树接到右子树的最左端。 第二,不改变左子树和右子树,为了保持排序树的特性,将左子树最大值节点替换待删除节点,或者是讲右子树最小值节点代替之。
#include <stdio.h>
#include <stdlib.h>
#include "Search.h"
//查找二叉排序树
//第一个参数:查询节点
//第二个参数:查找的键值
// 第三个参数:查找节点的父节点
//第四个参数:用于返回查找到的节点
int SearchBST(const pNode T,const ElemType key,pNode f,pNode &p)
{
if(!T){ p = f; return 0; } //节点不存在,返回最后一个节点,在数据插入其后
else if(key == T->data){p = T; return true; } //该节点在排序树中
else if(key > T->data) return SearchBST(T->rchild,key,T,p); //向右子树查找
else return SearchBST(T->lchild,key,T,p); //向左子树查找
}
//排序树中插入节点
//待插入节点的父节点,插入元素
int InsertBST(pNode T,const ElemType e)
{
pNode s;
s=(pNode)malloc(sizeof(tNode));
if(!s) return false;
s->data = e;
s->lchild = s->rchild = NULL; //到此构造节点结束
//这里在调试的时候要考虑树为空时的插入
//所以在初始化头结点的时候用255赋值给data
//左子树作为第一个节点
if(e < T->data) T->lchild = s; //在此进行插入
else T->rchild = s;
return true;
}
//排序树删除一个节点
//在此用引用的好处就是可以改变传递进来指针的值
int DeleteBST(pNode &T,ElemType key)
{
if(!T) return false; //节点不存在
else
{
if(key == T->data) return Delete( T ); //删除本节点
else if(key > T->data) return DeleteBST(T->rchild, key); //到右子树递归
else return DeleteBST( T->lchild,key); //到左子树递归
}
}
//进行删除操作
int Delete(pNode & T)
{
pNode p;
if(!T->rchild) //右子树有空,直接将左子树接到上面
{
p = T;
T = T->lchild;
free(p);
}
else if(!T->lchild) //左子树为空。直接将右子树接到上面
{
p = T;
T = T->rchild;
free(p);
}
else //左右子树都不为空
{
pNode s; //保存左子树的最大值节点
p = T; //保存s的父节点
s = T->lchild;
while(s->rchild) //根据特性,最右的节点最大
{
p = s;
s= s->rchild;
}
T->data = s->data; //待删除节点交换信息,相当于两节点置换
//当s的父节点就是待删除节点时,说明s就是T的左孩子
// 此时修改的是T的左孩子
//否则修改s父节点的右孩子
if(p != T) p->rchild = s->lchild;
else p->lchild = s->lchild;
free(s);
}
return true;
}
int main()
{
tNode head;
head.lchild = NULL; //树的第一个节点
head.rchild = NULL;
head.data = 0xFF; //可用于统计元素个数,在实现时为了操作简单,存放length-1;
while(1)
{
ElemType temp;
//pNode f = head.lchild;
pNode p = NULL;
printf("input the key:");
scanf("%d",&temp);
if(SearchBST(head.lchild,temp,&head,p))
{
printf("元素:%d存在树中!\n",p->data);
}
else
{
InsertBST(p,temp);
head.data++;
printf("I insert the key!\n");
}
}
return 0;
}
动态查找之二叉排序树
最新推荐文章于 2022-03-19 23:19:53 发布