数据结构–树(中)
二叉搜索树
对一颗二叉树,该如何实现它的动态查找(会有新元素的添加,和对当前树包含元素的删除),前面学过二分查找,很自然的如果我们再构建一棵树时,如果当前节点的左子树都比它小,右子树都比它大,对这样的树,我们叫做二叉搜索树。根据这样的性质,我们可以很自然的得出,二叉搜索树最小的节点是它的最左端的节点,二叉搜索树最大的节点是它的最右端的节点。
二叉搜索树的查找
我们知道对于一颗二叉搜索树,它任何节点的左子树都比它小,右节点都比它大,自然的一种二分查找,从根节点开始遍历,如果当前节点比需要查找的值大从它的左子树,比需要查找的值小从它的右子树。相等则返回。如果直到指向为空都无法找到,说明该结点并不在树上。
//find max value
Position FindMax(BinTree BST){
if(!BST){
return NULL;
}
while(BST->Right){
BST = BST->Right;
}
return BST;
}
//find min value
Position FindMin(BinTree BST){
if(!BST){
return NULL;
}
while(BST->Left){
BST = BST->Left;
}
return BST;
}
//find in value
Position Find(BinTree BST,ElementType X){
while(BST){
if(X>BST->Data){
BST = BST->Right;
}
else if(XData){
BST=BST->Left;
}
else{
return BST;
}
}
return BULL;
}
二叉搜索树的插入
同查找一个值一样,对于二叉搜索树的插入,先从根节点开始遍历,如果小于它就插入它的左子树,大于它就插入它的右子树。直到找到了位置,再申请一个结点将它接上去。
//insert
BinTree Insert(BinTree BST,ElementType X){
//if the tree is empty,create a node and return
if(!BST){
BST = malloc(sizeof(struct TNode));
BST->Data = X;
BST->Left = NULL;
BST->Right = NULL;
}
else{
if(X > BST->Data){
BST->Right = Insert(BST->Right,X);
}
else if(X < BST->DATA){
BAT->Left = Insert(BST->Left,X);
}
}
return BST;
}
二叉搜索树的删除
二叉树最多有两个节点,在删除时我们可能遇到几种情况,分别是该节点没有子节点(叶子节点),有一个子节点,有两个子节点。如果没有子节点,我们直接释放掉该节点,返回一个NULL接上去。如果只有一个子节点,我们只需要释放该节点,并把它的那个子节点接上去即可。有两个子节点时,问题变得麻烦起来,有一个策略就是,将问题转化为删除一个叶节点,或删除一个只有一个儿子的节点。通过二叉搜索树的性质我们知道,一颗树的最小值,位于他的最左端,最大值位于它的最右端,我们可以找到该节点右子树的最小值,赋值给该节点,同时删除掉它(因为二叉搜索树的性质,它只可能是叶节点,或者只有一个儿子,而且那样做不会破会二叉搜索树的一个节点左子树都比它小,右子树都比它大的性质),找该节点左子树的最大值同理。
//delete
BinTree Delete(BinTree BST,ElementType X){
if(!BST){
printf(“NOT Found\n”);
}
else{
//the Xis big than now position,delete X in its right tree
if(X > BST->Data){
BST->Right = Delete(BST->Right,X);
}
//the X is small than now position,delete X in its left tree
else if (X < BST->Data){
BST->Left = Delete(BST->Left,X);
}
//find the X position
else{
//has two sub tree
if(BST->Left && BST->Right){
BinTree temp = FindMax(BST->Left);
BST->Data = temp->Data;
temp->Data = X;
Delete(BST->Left,X);
}
//has one or no sub tree
else{
BinTree temp = BST;
//don’t has left sub tree
if(!BST->Left){
BST = BST->Right;
}
else if(!BST->Right){
BST = BST->Left;
}
free(temp);
}
}
}
return BST;
}