mian函数中的demo中,建树直接用循环加Insert操作集完成。二叉搜索树所有的操作:查找任意值、查找最大或最小值以及重点的插入和删除操作集都是基于查找来实现,其中有些操作集可以用循环或递归两种不同方法来实现,查找与插入都比较简单,重点注释了最难的delete操作集.
delete操作集:在二叉树中删除没有孩子的叶结点和只有1个孩子的根结点很容易实现,实现删除有左右孩子的结点就把它转化成解决删除一个结点的问题。假如被删除结点是有左右两个孩子的话,那就去找它左子树中的最大值或者右子树中的最小值来坐它的位置,去删除左子树中的最大值或者右子树中的最小值,因为左子树中的最大值或者右子树中的最小值一定是没有叶结点或者只有一个叶结点的,删除掉它很容易实现,并且让它去坐那个位置也不会破坏整棵搜索树的有序性。
#include <stdio.h>
#include <stdlib.h>
typedef int ElementType;
typedef struct TreeNode * BinTree;
typedef struct TreeNode{
ElementType Data;
BinTree LChild;
BinTree RChild;
}TreeNode;
typedef BinTree Position;
/*二叉搜索树的所有操作的精髓都是基于查找来实现*/
Position Find(BinTree BST,ElementType X);
Position FindPlus(BinTree BST,ElementType X);/*非递归查找*/
Position FindMin(BinTree BST);
Position FindMax(BinTree BST);/*找最大或最小值所在结点*/
BinTree Insert(BinTree BST,ElementType X);/*往二叉搜索树中插入新结点*/
BinTree Delete(BinTree BST,ElementType X);/*最重要,因为要删除的结点有三种情况
1.没有儿子 2.有1个儿子 3.有两个儿子,难点在于处理第三种情况
处理方法是:将被删除结点有两个儿子的问题转化为一个儿子或者没有儿子的情况*/
int main(void){
BinTree tree1 = NULL;
tree1 = Insert(tree1,33);
for(int i=89;i>33;i--)
{
tree1 = Insert(tree1,i);
}
printf("最小值 %d\n",FindMin(tree1)->Data);
printf("最大值 %d\n",FindMax(tree1)->Data);
printf("删除了值为89和33的结点\n");
tree1 = Delete(tree1,89);
tree1 = Delete(tree1,33);
printf("最小值 %d\n",FindMin(tree1)->Data);
printf("最大值 %d\n",FindMax(tree1)->Data);
return 0;
}
BinTree Delete(BinTree BST,ElementType X) /*重难点*/
{
Position Tmp;
if(BST == NULL) printf("要删除的结点未找到\n");
else if(X < BST->Data)
{
BST->LChild = Delete(BST->LChild,X);
}
else if(X > BST->Data)
{
BST->RChild = Delete(BST->RChild,X);
}
else
{
if(BST->LChild && BST->RChild)/*被删除结点有左右两个子结点*/
{
/*被删除结点的右子树中最小结点的值作为被删除结点的值,
从而将问题转化为删除被删除结点右子树中最左边的结点*/ /*也可以是被删除节点的左子树中的最大值来填充*/
Tmp = FindMin(BST->RChild);/*在右子树中找到最小的元素填充删除结点*/
BST->Data = Tmp->Data; /*将最小元素值提取出来,去做递归查找并删除*/
BST->RChild = Delete(BST->RChild,BST->Data);/*在删除结点的右子树中删除最小元素*/
}
else /*被删除结点有一个子结点或者没有子结点*/
{
Tmp = BST;
if(!BST->LChild) /*要删除的结点有右孩子和没有孩子的情况*/
BST = BST->RChild;
else if(!BST->RChild) /*要删除的结点有左孩子和没有孩子的情况*/
BST = BST->LChild;
free(Tmp); /*将空间释放*/
}
}
return BST;
}
Position Find(BinTree BST,ElementType X)
{
if(!BST) return NULL;
if(X<BST->Data)
{
return Find(BST->LChild,X);
}
else if(X>BST->Data)
{
return Find(BST->RChild,X);
}
else
return BST;
}
Position FindPlus(BinTree BST,ElementType X)
{
while(BST)
{
if(X<BST->Data)
{
BST = BST->LChild;
}
else if(X>BST->Data)
{
BST = BST->RChild;
}
else
break;
}
return BST;
}
Position FindMin(BinTree BST)
{
if(!BST) return NULL;
if(!BST->LChild) return BST;
else
{
return FindMin(BST->LChild);
}
}
Position FindMax(BinTree BST)
{
if(BST)
while(BST->RChild)
BST = BST->RChild;
return BST;
}
BinTree Insert(BinTree BST,ElementType X)
{
if(BST == NULL)
{
BST = (BinTree)malloc(sizeof(TreeNode));
BST->Data = X;
BST->LChild = BST->RChild = NULL;
}
else
{
if(X < BST->Data)
{
BST->LChild = Insert(BST->LChild,X);
}
else if(X > BST->Data)
{
BST->RChild = Insert(BST->RChild,X);
}
}
return BST;
}