一 概念
二叉排序树或者是空树,或者是满足如下性质的二叉树:
1.若它的左子树不空,则左子树上所有的关键字的值均小于根关键字的值。
2.若它的右子树不空,则右子树上所有关键字的值均大于根关键字的值。
3.左右子树又是一棵二叉排序树
二 BST的算法
1.查找关键字的算法
由BST的定义可知,根结点中的关键字将所有的关键字分成了两部分,即大于根节点中关键字的部分和小于根节点关键字的部分。可以将待查关键字先和根节点中关键字比较,如果相等则查找成功;如果相等则查找成功;如果小于则到左子树中去查找,如果大于则到右子树中查找。来到当前树的子树根中,重复上述过程。如果来到了结点的空指针与,则说明查找失败,实际上折半查找的判定树就是一个二叉排序树。
BTNode * BSTSearch(BTNode * bt,int key)
{
if(bt==NULL)
return NULL;
else
{
if(bt->weight==key)
return bt;
else if (key<bt->weight)
return BSTSearch(bt->lchild,key);
else
return BSTSearch(bt->rchild,key);
}
}
2.插入关键字算法
二叉排序树是一个查找表,插入一个关键字时首先要找到插入位置。对一个不存在于二叉排序数中的关键字,其查找不成功的位置即为该关键字的插入位置。因此只需对查找关键字的算法进行修改,在来到空指针的时候将关键字插入。
BTNode * Insert(BTNode * root,datatype w)
{
if(root==NULL)
{
root=(BTNode *)malloc(sizeof(BTNode));
root->weight=w;
root->lchild=NULL;
root->rchild=NULL;
return root;
}
else if ( root->weight==w )
return root;
else if (root !=NULL && w>root->weight)
{
root->rchild=Insert(root->rchild,w);
return root;
}
else
{
root->lchild=Insert(root->lchild,w);
return root;
}
}
3.二叉排序树的构造
二叉排序树的构造就变得非常简单,只需要建立一棵空树,然后将关键字逐个插入到空树中即可。
4.二叉排序树的删除
二叉排序树的删除分为三种情况
假设要删除的结点为*q,其双亲结点为*f,可设*p是*f的左孩子,分三种情况进行讨论
1)若*p结点为叶子结点,直接删除即可
2)*p只有右子树而无左子树,或者只有左子树而无右子树。此时只需将p删掉,然后将p的子树直接连接在原来p与其双亲结点f相连的指针上即可。
3)*p结点既有左子树又有右子树。将*p的直接前驱代替*p,然后删除p的直接前驱。但是要注意,删除p的直接前驱时,不要忘记把p的之间前驱s的左子树接到s的父节点的右子树上。
int del (BTNode * & p)//删除结点指针为p的结点
{
BTNode *q,*s;
if(p==NULL)
return ERROR ;
else
{
if(!p->lchild)//左子树为空只需要接右子树
{
q=p;p=p->rchild;free(q);
}
else if(!p->rchild)//右子树空
{
q=p;p=p->lchild;free(q);
}
else//左右为空,用中序遍历的p结点的前驱直接覆盖p的值,然后重接s的左右子树
{
q=p;s=p->lchild;
while(s->rchild){q=s;s=s->rchild;}
p->weight=s->weight;
if(q!=p) q->rchild=s->lchild;
else
q->lchild=s->lchild;//说明p的左子树的右子树空
free(s);
}
return OK;
}
}