二叉查找树操作
【问题描述】 编写一个操纵二叉查找树的程序。它将从标准输入接收命令,并将这些命令的响应 打印到标准输出。 二叉查找树是一棵二叉树,它在内部节点存储整数值。特定节点的值大于存储在其 左侧子树中的每个值,小于存储在其右侧子树中的每个值。该树不包含重复值。 请注意,在创建新节点时,需要使用malloc为它们分配空间;一旦不再需要任何已 分配的空间,就应该使用free将其释放。
【基本要求】 操纵二叉查找树的命令有4个: 插入n:向树中添加一个值,如果还没有的话,新节点将始终作为现有节点的子节 点或根节点添加,现有节点不会因为插入数据而改变或移动。如果n不存在,因此将被 插入,程序打印插入;否则,它将打印不插入。指令格式是一个i后跟一个十进制整数n。 搜索n:在树中搜索值n。如果n存在,程序将打印存在;否则会打印缺席。指令格 式是一个s后跟一个空格和一个整数n。 打印:空树(即空)被打印为空字符串。节点被打印为一个(,后跟左边的子树、该 节点的项、右边的子树和),没有空格。指令格式是一个p。例如,对应于图3-1的输出 是((1)2((3(4))5(6))) 删除n:从树中删除一个值。删除二叉树排序中的节点有几种策略。如果一个节点 没有子节点,可以简单地删除它;也就是说,指向它的指针可以更改为空指针。如果一 个节点有一个子节点,它可以被那个子节点替换。如果一个节点有两个子节点,其值将 被更改为其左子树中的最大元素,之前包含该值的节点将被删除。请注意,正在删除的 值可能在根节点上。指令格式是一个d后跟一个空格和一个整数n。
输入格式:输入将是一系列行,每一行都以一个命令字符(i、s、p或d)开始,后面 可能是一个十进制整数。当输入i、s、p或d之外的字符时,程序结束运行。
输出格式:输出将是一系列的行,响应每一个输入的命令,除了p之外,大多数命 令都会以一个单词来响应。 程序运行操作示例:(i、s、p或d开头的行是输入行,其他是输出行)
i 50
inserted
i 70
inserted
i 25
inserted
i 70
not inserted
i 55
inserted
p ((25)50((55)70))
s 55
present
s 60
absent
d 55
deleted
p ((25)50(70)
//二叉树节点类型定义
typedef int ElemType;
typedef int KeyType;
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
//按要求格式中序遍历输出
void PrintBST(BiTree T){
if(T == NULL){
return ;
}
printf("(");
PrintBST(T->lchild);
printf("%d", T->data);
PrintBST(T->rchild);
printf(")");
}
完整演示
#include<stdio.h>
#include <stdlib.h>
//二叉树节点类型定义
typedef int ElemType;
typedef int KeyType;
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
BiTree createNode(int data);
void PrintBST(BiTree T);
bool insert(BiTree *T,int n);
bool delet(BiTree* T,int n);
bool serch(BiTree T,int n);
void freeTree(BiTree root);
int main()
{
int n;
char e;
BiTree l = NULL;
bool m;
while(true){
scanf("%c",&e);
if(e == 'i'){
scanf("%d", &n);
m = insert(&l,n);
if(m){
printf("insert");
} else
printf("no insert");
}
if(e == 'd'){
scanf("%d",&n);
m = delet(&l,n);
if(m){
printf("delet");
} else
printf("false");
}
if(e == 's'){
scanf("%d", &n);
m = serch(l,n);
if(m){
printf("present");
} else
printf("abcent");
}
if(e == 'p'){
PrintBST(l) ;
}
}
freeTree(l);
return 0;
}
//按要求格式中序遍历输出
void PrintBST(BiTree T){
printf("(");
if(T -> lchild != NULL){
PrintBST(T->lchild);
}
printf("%d", T->data);
if( T -> rchild != NULL){
PrintBST(T->rchild);
}
printf(")");
}
bool serch(BiTree T,int n){
while(T)
{
if(n == T->data)
return true;
else if(n > T->data){
T= T->rchild;
serch(T,n);
}
else{
T = T -> lchild;
serch(T,n);
}
}
/*没有找到。返回NULL*/
return false;
}
BiTree createNode(int data){
BiTree newNode = (BiTree) malloc(sizeof(BiTNode));
newNode->data = data;
newNode->lchild = NULL;
newNode->rchild = NULL;
return newNode;
}
bool insert(BiTree *T,int n){
if(*T == NULL){
*T = createNode(n);
return true;
}
if(n == (*T)->data){
// printf("not inserted\n");
return false;
}
if(n< (*T)->data){
insert(&((*T)->lchild),n);
}else{
insert(&((*T)->rchild),n);
}
}
bool delet(BiTree *T,int n){
if(*T == NULL){
return false;
}
if(n == (*T)->data){
if((*T)->lchild== NULL){
(*T) = (*T)->rchild;
} else if((*T)->rchild == NULL){
(*T) = (*T)->lchild;
}else{
BiTree curr = (*T) ->lchild;
while (curr->rchild != NULL){
curr = curr->rchild;
}
(*T) ->data = curr->data;
delet(&((*T)->lchild),curr->data);
}
return true;
}
if(n < (*T)->data){
delet(&((*T)->lchild),n);
} else{
delet(&((*T)->rchild),n);
}
}
//释放树节点动态分配的内存
void freeTree(BiTree root){
if(root == NULL){
return;
}
freeTree(root->lchild);
freeTree(root->rchild);
free(root);
}