本题算法的基本思路如下:
①对源序列建树。
②对目标序列建树。
③将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
-
答疑:
- 解题遇到问题?分享解题心得?讨论本题请访问: 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);
}
}