6-12 二叉搜索树的操作集 (30 point(s))
本题要求实现给定二叉搜索树的5种常用操作。
函数接口定义:
BinTree Insert( BinTree BST, ElementType X );
BinTree Delete( BinTree BST, ElementType X );
Position Find( BinTree BST, ElementType X );
Position FindMin( BinTree BST );
Position FindMax( BinTree BST );
其中BinTree
结构定义如下:
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
- 函数
Insert
将X
插入二叉搜索树BST
并返回结果树的根结点指针; - 函数
Delete
将X
从二叉搜索树BST
中删除,并返回结果树的根结点指针;如果X
不在树中,则打印一行Not Found
并返回原树的根结点指针; - 函数
Find
在二叉搜索树BST
中找到X
,返回该结点的指针;如果找不到则返回空指针; - 函数
FindMin
返回二叉搜索树BST
中最小元结点的指针; - 函数
FindMax
返回二叉搜索树BST
中最大元结点的指针。
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
二叉搜素树的定义和链表的定义非常类似,相当于单项链表有两个指针
前序遍历
void PreorderTraversal(BinTree BT)
{
if (BT == NULL) // 递归终止条件
return;
printf("%d ", BT->Data);
PreorderTraversal(BT->Left);
PreorderTraversal(BT->Right);
}
中序遍历
void InorderTraversal(BinTree BT)
{
if (BT == NULL) // 递归终止条件
return;
InorderTraversal(BT->Left);
printf("%d ", BT->Data);
InorderTraversal(BT->Right);
}
二叉搜索树的查找
如果该值大于根节点的值,到右子树查找,如果该值小于根节点,到左子树查找
Position Find(BinTree BST, ElementType X)
{
while (BST)
{
if (BST->Data == X)
return BST;
else if (BST->Data > X)
{
BST = BST->Left;
}
else
{
BST = BST->Right;
}
}
return NULL;
}
查找二叉搜索树的最小值,一定在二叉树的最左端
Position FindMin(BinTree BST)
{
while (BST)
{
if (!BST->Left)
{ /* 如果已经到达二叉搜索树的最左端
那么此时为最小值*/
return BST;
}
BST = BST->Left;
}
if (BST == NULL)
return NULL;
}
查找二叉树搜索树的最大值,一定在二叉树的最右端
Position FindMax(BinTree BST)
{
while (BST)
{
if (!BST->Right)
{
/* 如果已经到达二叉搜索树的最右端
那么此时为最大值*/
return BST;
}
BST = BST->Right;
}
if (BST == NULL)
return NULL;
}
二叉树的插入,要返回根节点
这里插入是用递归的方法进行插入的
BinTree Insert(BinTree BST, ElementType X)
{
if (BST == NULL) // 递归终止条件
{
// 如果树为空,直接插入
BST = (BinTree)malloc(sizeof(struct TNode));
BST->Data = X;
BST->Left = NULL;
BST->Right = NULL;
}
else
{
if (BST->Data > X)
{
/* 如果当前结点大于X,那么将该结点插到BST->Left
返回的结点为BST->Left;
*/
BST->Left = Insert(BST->Left, X);
}
else if (BST->Data < X)
{
/* 如果当前结点小于X,那么将该结点插到BST->Right
返回的结点为BST->Right;
*/
BST->Right = Insert(BST->Right, X);
}
}
return BST;
}
删除的操作比较复杂,首先要找到要删除的节点,而且还要返回根节点
BinTree Delete(BinTree BST, ElementType X)
{
Position Tmp;
if (!BST)
{
// 如果没有找到要删除元素
printf("Not Found\n");
}
else
{
if (X < BST->Data)
{
BST->Left = Delete(BST->Left, X); // 如果X比较小,递归删除左子数,返回的根节点是BST->Left
}
else if (X > BST->Data)
{
BST->Right = Delete(BST->Right, X);
}
else
{
// BST就是要删除节点
if (BST->Left && BST->Right) // 如果被删除结点有左右子儿子
{
Tmp = FindMin(BST->Right); // 从右子数找一个最小值的节点
BST->Data = Tmp->Data; // 将右子数最小值赋值给要删除根节点
BST->Right = Delete(BST->Right, BST->Data); // 从右子数中删除最小值
}
else
{
// 被删除结点有一个或无子节点,与链表的删除相同
Tmp = BST;
if (!BST->Left)
{
// 如果没有左结点
BST = BST->Right;
}
else
{
// 如果没有右节点
BST = BST->Left;
}
free(Tmp);
}
}
}
return BST;
}