1.二叉排序树的定义
二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树(Binary Search Tree)。其定义为:二叉排序树或者是空树,或者是满足如下性质的二叉树:
①若它的左子树非空,则左子树上所有结点的值均小于根结点的值;
②若它的右子树非空,则右子树上所有结点的值均大于根结点的值;
③左、右子树本身又各是一棵二叉排序树。
2.二叉排序树的性质
按中序遍历二叉排序树,所得到的中序遍历序列是一个递增有序序列。
3.二叉排序树的插入
在二叉排序树中插入新结点,要保证插入后的二叉树仍符合二叉排序树的定义。
插入过程:
若二叉排序树为空,则待插入结点*S作为根结点插入到空树中;
4.二叉排序树的查找
假定二叉排序树的根结点指针为 root ,给定的关键字值为 K ,则查找算法可描述为:
① 置初值: q = root ;
② 如果 K = q -> key ,则查找成功,算法结束;
③ 否则,如果 K < q -> key ,而且 q 的左子树非空,则将 q 的左子树根送 q ,转步骤②;否则,查找失败,结束算法;
④ 否则,如果 K > q -> key ,而且 q 的右子树非空,则将 q 的右子树根送 q ,转步骤②;否则,查找失败,算法结束。
树结构:
二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树(Binary Search Tree)。其定义为:二叉排序树或者是空树,或者是满足如下性质的二叉树:
①若它的左子树非空,则左子树上所有结点的值均小于根结点的值;
②若它的右子树非空,则右子树上所有结点的值均大于根结点的值;
③左、右子树本身又各是一棵二叉排序树。
2.二叉排序树的性质
按中序遍历二叉排序树,所得到的中序遍历序列是一个递增有序序列。
3.二叉排序树的插入
在二叉排序树中插入新结点,要保证插入后的二叉树仍符合二叉排序树的定义。
插入过程:
若二叉排序树为空,则待插入结点*S作为根结点插入到空树中;
当非空时,将待插结点关键字S->key和树根关键字t->key进行比较,若s->key = t->key,则无须插入,若s->key< t->key,则插入到根的左子树中,若s->key> t->key,则插入到根的右子树中。而子树中的插入过程和在树中的插入过程相同,如此进行下去,直到把结点*s作为一个新的树叶插入到二叉排序树中,或者直到发现树已有相同关键字的结点为止。
//插入
int InsertBST(BiTree *T,int key)
{
BiTree p,s;
if(!SearchBST(*T,key,NULL,&p)) //查找不成功,可以插入
{
//s=(BiTree)malloc(sizeof(sizeof(BiTNode)));
s=(BiTree)malloc(sizeof(BiTNode));
s->data=key;
s->lchild=NULL;
s->rchild=NULL;
//查找不成功,指针p指向查找路径上访问的最后一个节点,返回FALSE
if(!p)//p为空,查找的为一颗空树
*T=s; //插入s为根节点
else if(key<p->data)
p->lchild = s;
else
p->rchild =s;
return true;
}
else
return false;
4.二叉排序树的查找
假定二叉排序树的根结点指针为 root ,给定的关键字值为 K ,则查找算法可描述为:
① 置初值: q = root ;
② 如果 K = q -> key ,则查找成功,算法结束;
③ 否则,如果 K < q -> key ,而且 q 的左子树非空,则将 q 的左子树根送 q ,转步骤②;否则,查找失败,结束算法;
④ 否则,如果 K > q -> key ,而且 q 的右子树非空,则将 q 的右子树根送 q ,转步骤②;否则,查找失败,算法结束。
/*
功能:二叉树的查找
key为要查找关键字
f指向T的双亲,当T为根节点时,f的初始值为NULL,它在递归时有用
查找成功,指针p指向该数据元素节点,返回TRUE
查找不成功,指针p指向查找路径上访问的最后一个节点,返回FALSE
*/
int SearchBST(BiTree T,int key,BiTree f,BiTree *p)
{
if(!T) //T为空,或者查找不成功
{
*p=f;
return false;
}
else if(key==T->data)
{
*p=T;
return true;
}
else if(key<T->data)
return SearchBST(T->lchild,key,T,p);
else if(key>T->data)
return SearchBST(T->rchild,key,T,p);
}
5.二叉排序树的删除
int Delete(BiTree *p)
{
BiTree q,s;
if((*p)->rchild == NULL)//右子树空
{
q=*p;
*p=(*p)->lchild;
free(q);
}
else if((*p)->lchild == NULL)//左子树空
{
q=*p;
*p=(*p)->rchild;
free(q);
}
else //左右子树都不为空
{
q=*p;
s=(*p)->lchild;//s指向*p的左孩子
while(s->rchild) //然后向右到尽头(找待删除节点的前驱)
{
q=s;
s=s->rchild;
}
(*p)->data = s->data; //s指向被删除节点的直接前驱
if(q!=*p) //重接q的右子树
q->rchild = s->lchild;
else
q->lchild =s->lchild; //重接q的左子树
free(s);
}
return true;
}
int DeleteBST(BiTree *T,int key)
{
if(!*T) //不存在关键字等于key的数据元素
return false;
else
{
if(key==(*T)->data)
return Delete(T);
else if(key < ((*T)->data))
return DeleteBST(&(*T)->lchild,key);
else
return DeleteBST(&(*T)->rchild,key);
}
}
树结构:
typedef struct BiTNode
{
int data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
测试:
int main()
{
int i;
int a[10]={62,88,58,47,35,73,51,99,37,93};
BiTree T=NULL;
//二叉排序树的构建
for(i=0;i<10;++i)
InsertBST(&T,a[i]);
//查找
BiTree p;
if(SearchBST(T,93,NULL,&p))
printf("已经找到关键字key=%d\n",p->data);
else
printf("没有找到\n");
DeleteBST(&T,93);
DeleteBST(&T,47);
if(SearchBST(T,93,NULL,&p))
printf("已经找到关键字key=%d\n",p->data);
else
printf("没有找到\n");
printf("%d\n",sizeof(7));
getchar();
return 0;
}