本题要求实现给定二叉搜索树的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
中最大元结点的指针。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
typedef int ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
void PreorderTraversal( BinTree BT ); /* 先序遍历,由裁判实现,细节不表 */
void InorderTraversal( BinTree BT ); /* 中序遍历,由裁判实现,细节不表 */
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 );
int main()
{
BinTree BST, MinP, MaxP, Tmp;
ElementType X;
int N, i;
BST = NULL;
scanf("%d", &N);
for ( i=0; i<N; i++ ) {
scanf("%d", &X);
BST = Insert(BST, X);
}
printf("Preorder:"); PreorderTraversal(BST); printf("\n");
MinP = FindMin(BST);
MaxP = FindMax(BST);
scanf("%d", &N);
for( i=0; i<N; i++ ) {
scanf("%d", &X);
Tmp = Find(BST, X);
if (Tmp == NULL) printf("%d is not found\n", X);
else {
printf("%d is found\n", Tmp->Data);
if (Tmp==MinP) printf("%d is the smallest key\n", Tmp->Data);
if (Tmp==MaxP) printf("%d is the largest key\n", Tmp->Data);
}
}
scanf("%d", &N);
for( i=0; i<N; i++ ) {
scanf("%d", &X);
BST = Delete(BST, X);
}
printf("Inorder:"); InorderTraversal(BST); printf("\n");
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
10
5 8 6 2 4 1 0 10 9 7
5
6 3 10 0 5
5
5 7 0 10 3
输出样例:
Preorder: 5 2 1 0 4 8 6 7 10 9
6 is found
3 is not found
10 is found
10 is the largest key
0 is found
0 is the smallest key
5 is found
Not Found
Inorder: 1 2 4 6 8 9
BinTree Insert( BinTree BST, ElementType X ){ BinTree p=BST; BinTree parent=NULL; BinTree newnode=(BinTree)malloc(sizeof(struct TNode)); newnode->Data=X; newnode->Left=NULL; newnode->Right=NULL; while(p!=NULL){//寻找合适位置插入 parent=p; if(X<p->Data){ p=p->Left; }else{ p=p->Right; } } if(parent==NULL){ BST=newnode; }else if(X<parent->Data){ parent->Left=newnode; }else{ parent->Right=newnode; } return BST; } BinTree Delete( BinTree BST, ElementType X ){ BinTree p=BST,parent=NULL;//如果父节点为NULL说明是根结点 int flag=1; while(p!=NULL){ if(X<p->Data){//小于从左子树找 parent=p;//标记父节点 p=p->Left; }else if(X>p->Data){//大于从右子树找 parent=p; p=p->Right; }else{//找到了要删除的结点 flag=0;//标记找到了结点 if(p->Left==NULL&&p->Right==NULL){//首先处理叶子结点 if(parent==NULL){//要删除的结点是 只有一个结点的根结点 直接返回空树 BST=NULL;//根节点置为空 break; }else{//非根的叶结点 //删除的结点小于父结点 则是左子结点 把父结点的左子结点置为NULL 反之是右子结点 (p->Data<parent->Data)?(parent->Left=NULL):(parent->Right=NULL); break; } }else if(p->Left==NULL&&p->Right!=NULL){//要删除的结点只有 右子树 if(parent==NULL){//该结点是根结点 没有父结点 BST=BST->Right; break; }else{//非根结点 //删除的结点小于父结点是左子结点 把父结点的左子结点指向删除结点的右子树 //反之是父结点的右子结点指向删除结点的右子树 (p->Data<parent->Data)?(parent->Left=p->Right):(parent->Right=p->Right); break; } }else if(p->Left!=NULL&&p->Right==NULL){//要删除的结点只有左子树 if(parent==NULL){//该结点是根结点 没有父结点 没有右子树 BST=BST->Left; break; }else { //删除的结点小于父结点是左子结点 把父结点的左子结点指向删除结点的左子树 //反之是父结点的右子结点指向删除结点的左子树 (p->Data<parent->Data)?(parent->Left=p->Left):(parent->Right=p->Left); break; // } }else{//要删除的结点有左子树同时有右子树 BinTree tempP=p;//需要一个新的结点 暂存p结点 //这里寻找p的前驱作为替换结点 也就是左子树的最大结点 p=p->Left;//从左子树开始找左子树的最大结点 while(p->Right!=NULL){//保存父结点的同时 一直找到左子树的最大值 parent=p; p=p->Right; } //父结点的右子树指向 最大值的的左子树 parent->Right=p->Left; //然后将最大值结点的左右子树 指向 删除结点的左右子树 tempP->Data=p->Data; break; } } } if(flag){ printf("Not Found\n"); } return BST; } Position Find( BinTree BST, ElementType X ){ BinTree p=BST; while(p!=NULL){ if(p->Data==X){ break; }else if(X<p->Data){ p=p->Left; }else{ p=p->Right; } } return p; } Position FindMin( BinTree BST ){ BinTree p=BST; while(p!=NULL){ if(p->Left==NULL){//直到最后一个左子树为空的结点就是最小结点 break; }else{ p=p->Left; } } return p; } Position FindMax( BinTree BST ){ BinTree p=BST; while(p!=NULL){ if(p->Right==NULL){//直到最后一个右子树为空的结点就是最大结点 break; }else{ p=p->Right; } } return p; }