1119. Pre- and Post-order Traversals (30)
2017-10-22 11:10
381 查看
题目链接:https://www.patest.cn/contests/pat-a-practise/1119
以题目给的例子说以下思路:
一、[1, 2, 3, 4, 6, 7, 5] [2, 6, 7, 4, 5, 3, 1]
1、前序遍历的第一个,后序遍历的最后一个节点的元素都为1,这是根节点
2、接下来判断该树是否唯一。
方法: 前序遍历完根节点后,应该会去遍历左子树;后序遍历最后一个元素是根节点,那么之前的元素应该是右子树的。这是左子树和右子树都存在的情况下。那么前序遍历的第二个节点应该是左子树的根节点,后序遍历的倒数第二个节点应该是右子树的根节点。如果这两个元素相同的话,这棵树就不唯一;不相同的话需要继续递归从而进行判断。
前序遍历的第二个节点为2,后序遍历的倒数第二个节点是3,所以目前为止这棵树是唯一的。
3、经过步骤2找到了根节点的左,右子树的”根节点”。之后需要确定左子树的前序遍历的序列,左子树的后序遍历的序列,然后进行递归建树的过程。
右子树的根节点元素为3,左子树的根节点元素为2。左子树的前序遍历序列为序列[1,2,3,4,6,7,5]中2到3(不包括3)之间的元素,即[2],左子树的后序遍历的为[2,6,7,4,5,3,1]为元素2(包括)之前的元素序列,即[2]
4、根据左子树的前,后遍历的序列,就可以知道右子树的前、后遍历的序列然后递归建树。
在本例中,右子树的前序遍历的序列为[1,2,3,4,6,7,5]中3(包括)之后的序列,即[3,4,6,7,5];右子树的后序遍历序列为[2,6,7,4,5,3,1] 中2(不包括)到3之间的元素,即[6,7,4,5,3]
二、在列二中
1 2 3 4
2 4 3 1
根节点为1,左,右子树的节点元素为2,3。但是在右子树的前序遍历序列[3,4]第二个元素和后序遍历序列[4,3]中倒数第二个元素相同,所以这棵树不唯一。
实现代码:
以题目给的例子说以下思路:
一、[1, 2, 3, 4, 6, 7, 5] [2, 6, 7, 4, 5, 3, 1]
1、前序遍历的第一个,后序遍历的最后一个节点的元素都为1,这是根节点
2、接下来判断该树是否唯一。
方法: 前序遍历完根节点后,应该会去遍历左子树;后序遍历最后一个元素是根节点,那么之前的元素应该是右子树的。这是左子树和右子树都存在的情况下。那么前序遍历的第二个节点应该是左子树的根节点,后序遍历的倒数第二个节点应该是右子树的根节点。如果这两个元素相同的话,这棵树就不唯一;不相同的话需要继续递归从而进行判断。
前序遍历的第二个节点为2,后序遍历的倒数第二个节点是3,所以目前为止这棵树是唯一的。
3、经过步骤2找到了根节点的左,右子树的”根节点”。之后需要确定左子树的前序遍历的序列,左子树的后序遍历的序列,然后进行递归建树的过程。
右子树的根节点元素为3,左子树的根节点元素为2。左子树的前序遍历序列为序列[1,2,3,4,6,7,5]中2到3(不包括3)之间的元素,即[2],左子树的后序遍历的为[2,6,7,4,5,3,1]为元素2(包括)之前的元素序列,即[2]
4、根据左子树的前,后遍历的序列,就可以知道右子树的前、后遍历的序列然后递归建树。
在本例中,右子树的前序遍历的序列为[1,2,3,4,6,7,5]中3(包括)之后的序列,即[3,4,6,7,5];右子树的后序遍历序列为[2,6,7,4,5,3,1] 中2(不包括)到3之间的元素,即[6,7,4,5,3]
二、在列二中
1 2 3 4
2 4 3 1
根节点为1,左,右子树的节点元素为2,3。但是在右子树的前序遍历序列[3,4]第二个元素和后序遍历序列[4,3]中倒数第二个元素相同,所以这棵树不唯一。
实现代码:
#include <iostream> #include <malloc.h> #include <vector> using namespace std; #define N 33 typedef struct BTree { struct BTree* left; int data; struct BTree* right; }BTree; bool isUnique=true;//用来存储该树是否唯一 vector<int> inseq;//存储中序遍历的序列 BTree* buildTree(int* pre,int* post,int n)//pre,p af0c ost分别为一棵树的前序,后序遍历 {//那么前序第一个,后序的最后一个一定相等,因为该节点为根节点 if(n==0)//递归结束的条件 return NULL; BTree* root=(BTree*)malloc(sizeof(BTree)); root->data=pre[0];//前序遍历的第一个节点(后序的最后一个节点)为根节点 if(1<n && n-2>=0 && pre[1]==post[n-2])//前序的第二个,后序的倒数第二个相等 isUnique=false;//则该树不唯一 int leftEnd=1;//记录左子树前序遍历的终止位置。下标1为开始的位置 while(leftEnd<n && pre[leftEnd]!=post[n-2]) leftEnd++; //递归左子树,需要找到左子树的前序,后序遍历序列 root->left=buildTree(pre+1,post,leftEnd-1); //递归右子树,右子树的前序,后序序列 root->right=buildTree(pre+leftEnd,post+leftEnd-1,n-leftEnd); return root; } void inOrder(BTree* root)//中序遍历 { if(root) { inOrder(root->left); inseq.push_back(root->data); inOrder(root->right); } } int main() { int n; int pre ,post ; cin>>n; for(int i=0;i<n;i++) cin>>pre[i]; for(int i=0;i<n;i++) cin>>post[i]; BTree* root=buildTree(pre,post,n);//建树 inOrder(root);//中序遍历 if(isUnique) cout<<"Yes"<<endl; else cout<<"No"<<endl; for(int i=0;i<inseq.size();i++) { if(i==inseq.size()-1) cout<<inseq[i]<<endl; else cout<<inseq[i]<<" "; } }
相关文章推荐
- PAT 1119. Pre- and Post-order Traversals (30) 用前序、后序求中序
- PAT A 1119. Pre- and Post-order Traversals (30)【二叉树遍历】
- 1119. Pre- and Post-order Traversals (30)
- Solution of 1119. Pre- and Post-order Traversals (30)
- PAT 1119. Pre- and Post-order Traversals (30)
- 1119. Pre- and Post-order Traversals (30)
- 1119. Pre- and Post-order Traversals (30)
- 1119. Pre- and Post-order Traversals (30)
- 1119. Pre- and Post-order Traversals (30)
- PAT甲题题解-1119. Pre- and Post-order Traversals (30)-(根据前序、后序求中序)
- 1119. Pre- and Post-order Traversals (30)-PAT甲级真题(前序后序转中序)
- pat 1119. Pre- and Post-order Traversals (30)
- PAT 1119. Pre- and Post-order Traversals (30)
- 1119. Pre- and Post-order Traversals (30) (先序+后序,确定二叉树?)
- [二叉树建树]1119. Pre- and Post-order Traversals (30) (前序和后序遍历建立二叉树)
- PAT甲级 1119. Pre- and Post-order Traversals (30)
- 1119. Pre- and Post-order Traversals (30)
- PAT 甲级 1119. Pre- and Post-order Traversals (30)
- PAT_A 1119. Pre- and Post-order Traversals (30)
- 【PAT】【Advanced Level】1119. Pre- and Post-order Traversals (30)