二叉树增删改查C语言实现

二叉查找树操作

【问题描述】 编写一个操纵二叉查找树的程序。它将从标准输入接收命令,并将这些命令的响应 打印到标准输出。 二叉查找树是一棵二叉树,它在内部节点存储整数值。特定节点的值大于存储在其 左侧子树中的每个值,小于存储在其右侧子树中的每个值。该树不包含重复值。 请注意,在创建新节点时,需要使用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);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值