二叉搜索树——浙大10年

题目描述

在这里插入图片描述

知识点

二叉搜索树,二叉树的遍历,二叉树是否相同的判断。

实现

码前思考

  1. 在一般情况下,我们知道前序遍历结果中序遍历结果,那么我们就能确定一棵二叉树。那么,我们可以从反面出发——如果两棵二叉树的前序遍历结果和后序遍历结果相同,那么它们是同一棵二叉树。这就是解题的思路啦~
  2. 由于二叉搜索树的特性,因此我们只需要判断前序遍历结果是否相同即可~

代码实现 (写错了)

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

const int maxn = 15; 

struct node{
	char data;
	node* lchild;
	node* rchild;
	node(char _data):data(_data),lchild(NULL),rchild(NULL){}
};

//输入的序列的多少 
int n; 

//原始输入字符串
char ina[maxn];
char inb[maxn];
int lena;
int lenb;

//输出的前序遍历字符串
char prea[maxn];
char preb[maxn];
int posa;
int posb; 

void insert(node* &root,char x){
	if(root == NULL){
		root = new node(x);
		return;
	}
	
	if(root->data > x){
		insert(root->lchild,x);
	}else{
		insert(root->rchild,x);
	}
}

node* create(char input[],int n){
	node* root = NULL;
	for(int i=0;i<n;i++){
		insert(root,input[i]);
	}
	return root;
}

void preOrder(node* root,char out[],int &pos){
	if(root == NULL){
		return;
	}
	
	out[pos++] = root->data;
	preOrder(root->lchild,out,pos);
	preOrder(root->rchild,out,pos);
}

int main(){
	while(~(scanf("%d",&n))){
		if(n==0){
			break;
		}
		
		scanf("%s",ina);
		lena = strlen(ina);
		
		//进行建树
		node* roota = NULL;
		roota = create(ina,lena); 
		
		//得到前序遍历结果
		posa=0;
		preOrder(roota,prea,posa); 
		
		for(int i=0;i<n;i++){
			scanf("%s",inb);
			lenb = strlen(inb);
			node* rootb = NULL;
			rootb = create(inb,lenb);
			posb=0;
			preOrder(rootb,preb,posb);
			
			if(!strcmp(prea,preb)){
				printf("YES\n"); 
			}else{
				printf("NO\n");
			}
		}
	}
	return 0;
} 

码后思考

  1. 嘤嘤嘤,我写错了,牛客的数据太弱了,我其实写错了:

  2. 在上面的代码中,我没有对 共享数据结构preb 进行初始化,导致如果前一次输入的字符串长度比后一次的要长,那么前一次的结果多出的部分会拼接到后一次末尾!!! 例如,下面的测试用例:

    2
    567432
    5432671
    543267
    
  3. 这已经是第二次遇到这个问题了,一定要对共享的字符数组初始化为空—— preb = ""(或者在最后面加ASCII码值0代表终止也是可以的)

  4. 很奇怪,对于全局变量的字符数组会默认全是ASCII码0,而对于局部变量就会默认是一堆乱码。。。这里一定要警醒了,以后用到一定要注意;

  5. scanf输入字符数组会自动在末尾加ASCII码0~所以之前才一直没有发现这个问题。 在这里插入图片描述
    正确代码:

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

const int maxn = 15; 

struct node{
	char data;
	node* lchild;
	node* rchild;
	node(char _data):data(_data),lchild(NULL),rchild(NULL){}
};

//输入的序列的多少 
int n; 

//原始输入字符串
char ina[maxn];
int lena;
int lenb;

//输出的前序遍历字符串
char prea[maxn];
int posa;
int posb; 

void insert(node* &root,char x){
	if(root == NULL){
		root = new node(x);
		return;
	}
	
	if(root->data > x){
		insert(root->lchild,x);
	}else{
		insert(root->rchild,x);
	}
}

node* create(char input[],int n){
	node* root = NULL;
	for(int i=0;i<n;i++){
		insert(root,input[i]);
	}
	return root;
}

void preOrder(node* root,char out[],int &pos){
	if(root == NULL){
		return;
	}
	
	out[pos] = root->data;
	pos++; 
	preOrder(root->lchild,out,pos);
	preOrder(root->rchild,out,pos);
}

int main(){
	while(~(scanf("%d",&n))){
		if(n==0){
			break;
		}
		
		scanf("%s",ina);
		lena = strlen(ina);
		
		//进行建树
		node* roota = NULL;
		roota = create(ina,lena); 
		
		//得到前序遍历结果
		posa=0;
		preOrder(roota,prea,posa); 
		prea[posa] = 0;
		
		for(int i=0;i<n;i++){
		
			char inb[maxn]="";
			
			scanf("%s",inb);

			lenb = strlen(inb);
			node* rootb = NULL;
			rootb = create(inb,lenb);
			
			char preb[maxn]="";
			
			posb=0;
			preOrder(rootb,preb,posb);
			preb[posb] = 0;
			
			if(!strcmp(prea,preb)){
				printf("YES\n"); 
			}else{
				printf("NO\n");
			}
		}
	}
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值