BST树的查找
1 查找思想
首先将给定的K值与二叉排序树的根结点的关键字进行比较:若相等: 则查找成功;
① 给定的K值小于BST的根结点的关键字:继续在该结点的左子树上进行查找;
② 给定的K值大于BST的根结点的关键字:继续在该结点的右子树上进行查找。
2 算法实现
⑴ 递归算法
BSTNode *BST_Serach(BSTNode *T , KeyType key)
{
if (T==NULL) return(NULL) ;
else
{
if (EQ(T->key, key) ) return(T) ;
else if ( LT(key, T->key) )
return(BST_Serach(T->Lchild, key)) ;
else return(BST_Serach(T->Rchild, key)) ;
}
}
⑵ 非递归算法
BSTNode *BST_Serach(BSTNode *T , KeyType key)
{
BSTNode p=T ;
while (p!=NULL&& !EQ(p->key, key) )
{
if ( LT(key, p->key) ) p=p->Lchild ;
else p=p->Rchild ;
}
if (EQ(p->key, key) ) return(p) ;
else return(NULL) ;
}
在随机情况下,二叉排序树的平均查找长度ASL和㏒(n)(树的深度)是等数量级的。
BST树的插入
在BST树中插入一个新结点,要保证插入后仍满足BST的性质。
1 插入思想
在BST树中插入一个新结点x时,若BST树为空,则令新结点x为插入后BST树的根结点;否则,将结点x的关键字与根结点T的关键字进行比较:
① 若相等: 不需要插入;
② 若x.key<T->key:结点x插入到T的左子树中;
③ 若x.key>T->key:结点x插入到T的右子树中。
2 算法实现
⑴ 递归算法
void Insert_BST (BSTNode *T , KeyType key)
{
BSTNode *x ;
x=(BSTNode *)malloc(sizeof(BSTNode)) ;
X->key=key; x->Lchild=x->Rchild=NULL ;
if (T==NULL) T=x ;
else
{
if (EQ(T->key, x->key) ) return ;/* 已有结点 */
else if (LT(x->key, T->key) )
Insert_BST(T->Lchild, key) ;
else Insert_BST(T->Rchild, key) ; }
}
⑵ 非递归算法
void Insert_BST (BSTNode *T , KeyType key)
{
BSTNode *x, *p , *q ;
x=(BSTNode *)malloc(sizeof(BSTNode)) ;
X->key=key;
x->Lchild=x->Rchild=NULL ;
if (T==NULL) T=x ;
else
{
p=T ;
while (p!=NULL)
{
if (EQ(p->key, x->key) ) return ;
q=p ; /*q作为p的父结点 */
if (LT(x->key, p->key) ) p=p->Lchild ;
else p=p->Rchild ;
}
if (LT(x->key, q->key) ) q->Lchild=x ;
else q->Rchild=x ;
}
}
由结论知,对于一个无序序列可以通过构造一棵BST树而变成一个有序序列。
由算法知,每次插入的新结点都是BST树的叶子结点,即在插入时不必移动其它结点,仅需修改某个结点的指针。
利用BST树的插入操作,可以从空树开始逐个插入每个结点,从而建立一棵BST树,算法如下:
#define ENDKEY 65535
BSTNode *create_BST()
{
KeyType key ;
BSTNode *T=NULL ;
scanf(“%d”, &key) ;
while (key!=ENDKEY)
{
Insert_BST(T, key) ;
scanf(“%d”, &key) ;
}
return(T) ;
}