BinTree Insert( BinTree BST, ElementType X){
if( !BST){ //若为空,生成并返回一个结点的二叉搜索树
BST = (BinTree)malloc(sizeof(struct TNode));
BST->Left = BST->Right = NULL;
BST->Data = X;
}else{
if( X > BST->Data)
BST->Right = Insert( BST->Right, X);//将子树的根结点返回给BST->Right
else if( X < BST->Data)
BST->Left = Insert( BST->Left, X);//将子树的根结点返回给BST->Left
}
return BST;
}
Position Find( BinTree BST, ElementType X ){
while( BST){
if( X > BST->Data) BST = BST->Right;//向右子树中查找
else if( X < BST->Data) BST = BST->Left;//向左子树中查找
else break;//查找成功,跳出循环,返回当前结点
}
return BST;
}
Position FindMin( BinTree BST){
while( BST){
if( BST->Left) BST = BST->Left;
else break;//一直向左查找,直到再无左子树,即为最小值
}
return BST;
}
Position FindMax( BinTree BST){
while( BST){
if( BST->Right) BST = BST->Right;
else break;
}
return BST;
}
BinTree Delete( BinTree BST, ElementType X ){
Position temp;
if( !BST) printf("Not Found\n");//没有找到要删除的元素
else{
if( X > BST->Data) BST->Right = Delete( BST->Right, X);//向右子树递归删除
else if( X < BST->Data) BST->Left = Delete( BST->Left, X);//向左子树递归删除
else{//BST即为要删除的结点
if( BST->Left && BST->Right){//BST为有两个子结点的情况
temp = FindMin( BST->Right);//找到右子树中的最小结点
BST->Data = temp->Data;//把BST的数值更改为temp数值,即删除
BST->Right = Delete( BST->Right, BST->Data);//删除掉右子树中最小结点
}else{//被删除结点只有一个结点或者无结点
temp = BST;
if( !BST->Left) BST = BST->Right;//只有右结点或者无子结点
else BST = BST->Left;//只有左结点
free(temp);
}
}
}
return BST;
}
如果要删除的是叶结点,可以直接删除,然后再修改其父结点的指针,置空即可。
如果要删除的结点只有一个孩子结点,删除之前需要改变其父结点的指针,指向要删除结点的孩子结点。即改变BST的值。(返回的BST即父结点的子结点)
在被删除结点有两个结点的情况下,可以选择左子树中的最大结点或者右子树中的最小结点替换掉要删除的结点,这样可以保证被替换的结点大于左子树,小于右子树。可知,此结点最多只有一个子结点,否则不满足最大或者最小的条件。可以利用删除只有一个子结点的结点的方法删除掉被选中的该结点。
在删除的操作中,函数的返回值是根节点,BST->Right = Delete( BST->Right, X),即把删除操作后的子树的节点赋给BST->Right,并不影响BST的数值。递归的最后操作完成逐层后返时,将更新左右子树的节点,最终返回该树的根节点。