期末数据结构实训(c++版)——二叉排序树的插入删除和查找

pre: 前序遍历
in: 中序遍历
post:后序遍历
insert: 插入,本题中不会出现相同的元素
delete: 删除,删除成功输出TRUE,没有该元素则输出FALSE,删除的方法是如果有左子树,以左子树中最大值作为新的树根,否则,以右子树最小值作为树根。
search: 查找,存在该元素输出YES, 否则输出NO
exit:退出
输入:
输入的第一行为整数 N
接下来一行为N个整数,你需要把这N个整数构建出相应的二叉排序树
之后是一组指令。

输出:
根据相应的指令进行输出。说明:遍历各元素之间用一个空格隔开。

样例输入:
10
31 15 9 5 4 7 8 50 42 2
pre
in
post
delete
15
delete
88
in
search
8
search
222
insert
15
pre
in
post
exit

样例输出:

31 15 9 5 4 2 7 8 50 42
2 4 5 7 8 9 15 31 42 50
2 4 8 7 5 9 15 42 50 31
TRUE
FALSE
2 4 5 7 8 9 31 42 50
YES
NO
31 9 5 4 2 7 8 15 50 42
2 4 5 7 8 9 15 31 42 50
2 4 8 7 5 15 9 42 50 31

注意:在样例中,我先把15删除掉了,然后再插入15,观察最开始的三个遍历,和最后的三次遍历,遍历结果是有区别的。

解释见注释

ac代码:

#include<bits/stdc++.h>
using namespace std;

const int N=1010;
int m;
int x,l[N],r[N],a[N],idx=1,root;

//根节点用引用的形式可以省一些代码
void insert(int &p,int x)
{
	//如果该位置为空就把x插入该位置
	if(!p)
	{
		p=idx;
		//存一下该地址对应的值
		a[idx++]=x;
		return ;
	}
	
	//如果x<此节点的值,就插入该节点的左边,否则则插入右边
	if(x<a[p]) insert(l[p],x);
	else insert(r[p],x);
}

void qian(int p)
{
	//根左右
	cout<<a[p]<<" ";
	if(l[p])qian(l[p]);
	if(r[p])qian(r[p]);
}

void zhong(int p)
{
	//左根右
	if(l[p])zhong(l[p]);
	cout<<a[p]<<" ";
	if(r[p])zhong(r[p]);
}

void hou(int p)
{
	//左右根
	if(l[p])hou(l[p]);
	if(r[p])hou(r[p]);
	cout<<a[p]<<" ";
}

void delate(int &p,int x)
{
	//找到改元素之后,进行修改
	if(a[p]==x)
	{
		//存在左子树,找最大及左子树最右,将它删除,并将p点改为改值
		if(l[p]){
			int ll=l[p];
			int rr=r[p];
			int x=l[p],f=0;
			while(r[x])f=x,x=r[x];
			if(f){
				r[f]=l[x];
				p=x;
				l[p]=ll,r[p]=rr;
			}
			else{
				p=x;
				r[p]=rr;
			}
		}
		//如果不存在左子树,就去右子树找最小及最左,将它删除,并将p点改为该值
		else{
			int ll=l[p];
			int rr=r[p];
			int x=r[p],f=0;
			while(l[x])f=x,x=l[x];
			if(f){
				l[f]=r[x];
				p=x;
				l[p]=ll,r[p]=rr;
			}
			else{
				p=x;
				l[p]=ll;
			}
		}
		//删除完成
		return ;
	}
	
	//先找到再说
	if(x<a[p])delate(l[p], x);
	else delate(r[p],x);
}

bool search(int p,int x)
{
	if(p==0)return 0;
	if(a[p]==x) return 1;
	
	
	if(x<a[p])return search(l[p], x);
	else return search(r[p],x);
	return 0;
}

int main()
{
	
	//建树
	cin>>m;
	for(int i=0;i<m;i++) {cin>>x;insert(root,x);}
	
	int x;
	string op;
	while(cin>>op)
	{    
		if(op=="exit") break;
		else if(op=="pre") qian(root),cout<<endl;
		else if(op=="in") zhong(root),cout<<endl;
		else if(op=="post")hou(root),cout<<endl;
		else if(op=="delete")
		{
			cin>>x;
			if(search(root,x)) delate(root,x),cout<<"TRUE"<<endl;
			else cout<<"FALSE"<<endl;
		}
		else if(op=="insert")cin>>x,insert(root,x);
		else if(op=="search")
		{
			cin>>x;
			if(search(root,x)) cout<<"YES"<<endl;
			else cout<<"NO"<<endl;
		}
	}
	
}

  • 20
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值