九度OJ-1009-二叉搜索树

  本题算法的基本思路如下:

  ①对源序列建树。

  ②对目标序列建树。

  ③将isEqu标志置true。

  ④对源序列与目标序列分别先序遍历,并引入两个栈结构在递归遍历时不断压入各自的遍历序列。

  ⑤对两个栈进行比对,若出现不同则isEqu=false。

  ⑥使用相同的方法得到两个中序遍历序列并比对。

  ⑦输出结果。



  有如下收获:

  ①判断两棵二叉树是否相同,只要分别比对他们的先序和中序序列。包括中序在内的两种遍历结果可以唯一确定一棵二叉树。

  ②在树的遍历中想要记录下遍历到的结点的data,使用数组的话要辅以一个游标记录位置,并且此游标必须要在函数之外初始化,十分的麻烦。这时可以引入栈结构,每次递归调用只需压栈即可。(队列同理)

  ③二叉树的一种很重要的实现方式:直接使用elem数组而非struct结构体来表示二叉树,用下标作为游标代替左右指针。i结点的左子树下标即2i,右即2i+1。

  此法的前提条件:二叉树的密度必须大,即不能是稀疏树。否则空间利用率将会极低,从而在处理层数较多的BST(如单支树)时造成内存超载。

  此法的优点(较之结构体实现方式):

    1.免去了结点内存空间的申请、清理等,大大提升了程序时空效率,减小了代码量。

    2.由于将构建完毕的二叉树直接存储在线性结构而非链式结构中,在进行两棵树的比对时可以直接进行线性遍历逐位比较,而无需进行先序、中序两步,大大提高效率。

    综上,在条件允许的情况之下(最坏情况下不会造成内存过载),尽量使用此法,可以大大提升效率,精简代码。判断合适与否的方式:譬如此题,最多只有10个结点,最坏情况下共10层(单支树),在数组实现方式下需要2^10-1=1023大小的数组,在可接受范围之内。


题目地址:点击打开链接 题目描述:
判断两序列是否为同一二叉搜索树序列
输入:
开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束。
接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉搜索树。
接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉搜索树。
输出:

如果序列相同则输出YES,否则输出NO

样例输入:
2
567432
543267
576342
0
样例输出:
YES
NO
来源:
2010年浙江大学计算机及软件工程研究生机试真题
答疑:
解题遇到问题?分享解题心得?讨论本题请访问: http://t.jobdu.com/thread-7733-1-1.html


链式结构实现如下:

#include <iostream> 
#include <cstring>
#include <stack>
using namespace std;
typedef struct BiNode{
	struct BiNode* lc;
	struct BiNode* rc;
	int data;
}*BiTree;

BiTree createNode(int x);
BiTree insertNode(BiTree &T,int x);
void freeTree(BiTree &T);
void printTree(BiTree T);
void preOrder(BiTree T,stack<int> &seq);
void inOrder(BiTree T,stack<int> &seq);

int main(){
	int n;
	char s[20];
	BiTree T=NULL,U=NULL;
	stack<int> seqT; 
	stack<int> seqU;
	bool isEqu;
	while (cin>>n){
		//initiate
		freeTree(T);
		cin>>s;
		//createTree T
		for (int i=0;s[i]!='\0';i++){
			insertNode(T,s[i]+1-'1');
		}
		//n line comparing
		for (int index=0;index<n;index++){
			//initiate
			freeTree(U);
			isEqu=true;
			cin>>s;
			//createTree U
			for (int i=0;s[i]!='\0';i++){
				insertNode(U,s[i]+1-'1');
			}
			//compare
				//initiate stack
			while (!seqT.empty()){
				seqT.pop();
			}
			while (!seqT.empty()){
				seqT.pop();
			}
				//preOrder
			preOrder(T,seqT);
			preOrder(U,seqU);
			while (!seqT.empty()){
				if (seqT.top()!=seqU.top()){
					isEqu=false;
					break;
				}
				seqT.pop();
				seqU.pop();
			}
				//initiate stack
			while (!seqT.empty()){
				seqT.pop();
			}
			while (!seqT.empty()){
				seqT.pop();
			}
				//inOrder
			if (isEqu==true){	
				inOrder(T,seqT);
				inOrder(U,seqU);
				while (!seqT.empty()){
					if (seqT.top()!=seqU.top()){
						isEqu=false;
						break;
					}
					seqT.pop();
					seqU.pop();
				}
			}
			//cout
			if (isEqu==true)
				cout<<"YES"<<endl;
			else 
				cout<<"NO"<<endl;
		}

	}
	return true;
}
BiTree createNode(int x){
	BiTree T=new BiNode;
	T->lc=T->rc=NULL;
	T->data=x;
	return T;
}
BiTree insertNode(BiTree &T,int x){
	if (T==NULL){
		return T=createNode(x);
	}
	else {
		if (x<T->data)
			return insertNode(T->lc,x);
		else 
			return insertNode(T->rc,x);
	}
}
void freeTree(BiTree &T){
	if (T!=NULL){
		freeTree(T->lc);
		freeTree(T->rc);
		delete T;
		T=NULL;
	}
}
void printTree(BiTree T){
	if (T!=NULL){
		cout<<T->data;
		printTree(T->lc);
		printTree(T->rc);
	}
}
void preOrder(BiTree T,stack<int> &seq){
	if (T!=NULL){
		seq.push(T->data);
		preOrder(T->lc,seq);
		preOrder(T->rc,seq);
	}
}
void inOrder(BiTree T,stack<int> &seq){
	if (T!=NULL){
		inOrder(T->lc,seq);
		seq.push(T->data);
		inOrder(T->rc,seq);
	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值