Each input file contains one test case. For each case, the first line gives a positive integer N (<=30), the total number of nodes in the binary tree. The second line gives the postorder sequence and the third line gives the inorder sequence. All the numbers in a line are separated by a space.
For each test case, print in one line the level order traversal sequence of the corresponding binary tree. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.
7<br/>2 3 1 5 7 6 4<br/>1 2 3 4 5 6 7
4 1 6 3 5 7 2
#include<stdio.h>
#include<iostream>
#include<string>
#include<queue>
using namespace std;
struct Node
{
int data;
Node *left;
Node *right;
};
Node* find(int N,int *postorder,int *inorder,int postorderRoot,int inorderfirst,int inorderlast)
{
//找到这个数再中序中的位置
if(inorderfirst>inorderlast||inorderfirst<0||inorderlast>N-1)
{
return NULL;
}else if(inorderfirst==inorderlast)
{
Node *tmp = new Node();
tmp->data = inorder[inorderfirst];
return tmp;
}
int inorderIndex = -1;
for(int i=0;i<N;i++)
{
if(postorder[postorderRoot]==inorder[i])
{
inorderIndex=i;
break;
}
}
if(inorderIndex==-1)
return NULL;
Node *tmp = new Node();
tmp->data = postorder[postorderRoot];
tmp->left = find(N,postorder,inorder,postorderRoot-(inorderlast-inorderIndex+1),inorderfirst,inorderIndex-1);
tmp->right = find(N,postorder,inorder,postorderRoot-1,inorderIndex+1,inorderlast);
return tmp;
}
void cengcibianli(Node *root)
{
queue<Node*> queue;
queue.push(root);
bool isFirst = true;
while(!queue.empty())
{
Node *tmp = queue.front();
if(!isFirst){
cout<<" ";
}
isFirst=false;
cout<<tmp->data;
if(tmp->left!=NULL)
queue.push(tmp->left);
if(tmp->right!=NULL)
queue.push(tmp->right);
queue.pop();
}
cout<<endl;
}
int main()
{
int N;
scanf("%d",&N);
int *postorder = new int[N];
int *inorder = new int[N];
for(int i=0;i<N;i++)
{
scanf("%d",&postorder[i]);
}
for(int i=0;i<N;i++)
{
scanf("%d",&inorder[i]);
}
Node *root = find(N,postorder,inorder,N-1,0,N-1);
cengcibianli(root);
return 0;
}
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
/**
* 1020. Tree Traversals (25)
*
* @author Jacob
*
*/
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] postorder = new int[n];
int[] inorder = new int[n];
for (int i = 0; i < n; i++)
postorder[i] = sc.nextInt();
for (int i = 0; i < n; i++)
inorder[i] = sc.nextInt();
Node root = rebuild(postorder, 0, n - 1, inorder, 0, n - 1);
Queue<Node> queue = new LinkedList<Node>();
queue.offer(root);
ArrayList<Integer> res = new ArrayList<Integer>();
while (!queue.isEmpty()) {
Node node = queue.poll();
res.add(node.value);
if (node.left != null)
queue.offer(node.left);
if (node.right != null)
queue.offer(node.right);
}
System.out.print(res.get(0));
for (int i = 1; i < res.size(); i++) {
System.out.print(" " + res.get(i));
}
sc.close();
}
private static Node rebuild(int[] postorder, int postLeft, int postRight, int[] inorder, int inLeft, int inRight) {
// System.out.println("hhhhhhhhhhh:"+postLeft+" "+postRight+" "+inLeft+" "+inRight);
if (postLeft > postRight)
return null;
Node root = new Node(postorder[postRight]);
int index = 0;
for (int i = inLeft; i <= inRight; i++) {
if (inorder[i] == postorder[postRight])
index = i;
}
int leftNum = index - inLeft;
root.left = rebuild(postorder, postLeft, postLeft + leftNum - 1, inorder, inLeft, index - 1);
root.right = rebuild(postorder, postLeft + leftNum, postRight - 1, inorder, index + 1, inRight);
return root;
}
/*
* 构造树节点类
*/
static class Node {
public Node(int value) {
this.value = value;
}
int value;
Node left;
Node right;
}
}
#include <iostream>
#include <queue>
#include <cmath>
using namespace std;
#define maxn 35
struct node{ //定义树的结点(静态实现)
int data,lchild,rchild;
}Node[maxn];
int post[maxn],in[maxn],n,num=0;
int create(int inL,int inR,int postL,int postR){
if(postL>postR) return -1; //若后序序列长度小于等于0
int root=num++;
Node[root].data=post[postR]; //后序最后一个结点即为根结点
int mid;
for(mid=inL;mid<=inR;mid++){ //在中序中找到根结点
if(in[mid]==post[postR]) break;
}
Node[root].lchild=create(inL,mid-1,postL,postL+(mid-inL)-1); //返回右子树根结点地址(数组下标)
Node[root].rchild=create(mid+1,inR,postL+(mid-inL),postR-1);
return root;
}
void layerOrder(int root){ //层次遍历
queue<int> q;
q.push(root);
while(!q.empty()){
int now=q.front();
q.pop();
cout<<Node[now].data;
if(Node[now].lchild!=-1) q.push(Node[now].lchild);
if(Node[now].rchild!=-1) q.push(Node[now].rchild);
if(!q.empty()) cout<<" ";
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++)
cin>>post[i];
for(int i=0;i<n;i++)
cin>>in[i];
int root=create(0,n-1,0,n-1); //构建二叉树并返回根结点地址
layerOrder(root);
return 0;
} #include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 30;
int in_order[maxn], post_order[maxn];
int n, root, lch[maxn], rch[maxn]; //n为树的结点个数
vector<int> level;
void read_list(int *a){
int x;
for(int i=0;i<n;i++){
cin >> x;
a[i] = x;
}
}
//把in_order[L1 ... R1] 和 post_order[L2 ... R2] 建成一棵二叉树
int build(int L1, int R1, int L2, int R2){
if(L1 > R1) return 0;
int proot = post_order[R2], pos;
for(int i=0;i<n;i++){
if(in_order[i] == proot){
pos = i;
break;
}
}
int l_num = pos - L1; //左子树的结点个数
lch[proot] = build(L1, pos-1, L2, L2+l_num-1);
rch[proot] = build(pos+1, R1, L2+l_num, R2-1);
return proot;
}
void level_order(int proot){
queue<int> q;
q.push(proot);
while(!q.empty()){
int u = q.front();
q.pop();
level.push_back(u);
if(lch[u]) q.push(lch[u]);
if(rch[u]) q.push(rch[u]);
}
}
int main(){
cin >> n;
memset(lch, 0, sizeof(lch));
memset(rch, 0, sizeof(rch));
read_list(post_order);
read_list(in_order);
build(0, n-1, 0, n-1);
level_order(post_order[n-1]);
cout << level[0];
for(unsigned int i=1;i<level.size();i++)
cout << " " << level[i];
return 0;
} 算是比较典型吧
#include<cstdio>
#include<queue>
using namespace std;
struct Node {
int data;
Node *l;
Node *r;
};
int p[31], i[31],c[31],cnt=0;
Node *root;
queue<Node*> q;
Node* create(int pl, int pr, int il, int ir) {
if (pl > pr || il > ir) {
return NULL;
}
Node* root = new Node;
root->data = p[pr];
int k;
for (k = il;k<=ir; k++) {
if (i[k] == p[pr])
break;
}
int nl = k - il;
root->l = create(pl, pl + nl - 1, il, k - 1);
root->r = create(pl + nl, pr - 1, k + 1, ir);
return root;
}
void BFS(Node *n) {
q.push(n);
while (!q.empty()) {
Node *temp = q.front();
q.pop();
c[cnt++] = temp->data;
if (temp->l != NULL)
q.push(temp->l);
if (temp->r != NULL)
q.push(temp->r);
}
}
int main() {
int N;
scanf("%d", &N);
for (int i = 1; i <= N; i++) {
scanf("%d", &p[i]);
}
for (int j = 1; j <= N; j++) {
scanf("%d", &i[j]);
}
root=create(1,N,1,N);
BFS(root);
for (int i = 0; i < N; i++) {
printf("%d", c[i]);
if (i < N - 1)
printf(" ");
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
struct node {
int data;
node* lchild;
node* rchild;
node(int a):data(a),lchild(NULL),rchild(NULL) {
}
};
const int Max=50;
int n,P[Max],I[Max];
node* create(int p1,int p2,int i1,int i2) {
if(p1>p2) {
return NULL;
}
node* root=new node(P[p2]);
int k;
for(k=i1; k<=i2; k++) {
if(I[k]==P[p2]) {
break;
}
}
int num=k-i1;
root->lchild=create(p1,p1+num-1,i1,k-1);
root->rchild=create(p1+num,p2-1,k+1,i2);
return root;
}
int num=0;
void BFS(node* root) {
queue<node*> q;
q.push(root);
while(!q.empty()) {
node* now=q.front();
q.pop();
cout<<now->data;
num++;
if(num<n) cout<<" ";
if(now->lchild!=NULL) {
q.push(now->lchild);
}
if(now->rchild!=NULL) {
q.push(now->rchild);
}
}
}
int main() {
while(cin>>n) {
for(int i=0; i<n; i++) {
cin>>P[i];
}
for(int i=0; i<n; i++) {
cin>>I[i];
}
node* root=create(0,n-1,0,n-1);
BFS(root);
}
return 0;
} 思路:不构建二叉树,使用队列+下标逐级分解二叉树
1、后序遍历最后一节点为根节点
2、中序二叉树中根节点的位置可以确定左右子树的中序遍历 和 对应的节点数
3、根据节点数,可以在后序遍历中得到左右子树的后序遍历
#include<iostream>
using namespace std;
int main()
{
int n, post[35], in[35], i;
int s1[35], e1[35], s2[35], e2[35], front, end;
cin >> n;
for (i = 0; i < n; ++i)
cin >> post[i];
for (i = 0; i < n; ++i)
cin >> in[i];
front = -1, end = 0;
s1[end] = s2[end] = 0;
e1[end] = e2[end] = n-1;
while(end != front)
{
if (front != -1)
cout << " ";
cout << post[e1[++front]];
for (i = s2[front]; i <= e2[front]; ++i)
if (in[i] == post[e1[front]])
break;
if (s1[front] != e1[front])
{
if (i > s2[front])
{
s1[++end] = s1[front];
e1[end] = s1[front]+i-s2[front]-1;
s2[end] = s2[front];
e2[end] = i-1;
}
if (i < e2[front])
{
s1[++end] = s1[front]+i-s2[front];
e1[end] = e1[front]-1;
s2[end] = i+1;
e2[end] = e2[front];
}
}
}
return 0;
}
别的大佬的一个不需要重构的方法,利用了层次遍历的性质 #include <cstdio>
#include <vector>
#include <map>
using namespace std;
vector<int> post, in;
map<int, int> level;
void pre(int root, int start, int end, int index) {
if(start > end) return ;
int i = start;
while(i < end && in[i] != post[root]) i++;
level[index] = post[root];
pre(root - 1 - end + i, start, i - 1, 2 * index + 1);
pre(root - 1, i + 1, end, 2 * index + 2);
}
int main() {
int n;
scanf("%d", &n);
post.resize(n);
in.resize(n);
for(int i = 0; i < n; i++) scanf("%d", &post[i]);
for(int i = 0; i < n; i++) scanf("%d", &in[i]);
pre(n-1, 0, n-1, 0);
auto it = level.begin();
printf("%d", it->second);
while(++it != level.end()) printf(" %d", it->second);
return 0;
} |
#include<bits/stdc++.h>
using namespace std;
struct Tree{
int data;
Tree* left;
Tree* right;
};
Tree* createTree(int a[],int b[],int l1,int h1,int l2,int h2){
//a是后序遍历数组,b是中序遍历数组,l1,h1为后序第一个和最后一个下标,l2和h2是中序第一个和最后一个下标
Tree* root=new Tree;
if(h1>=0){
root->data=a[h1];
}
int i;
for(i=l2;b[i]!=root->data;i++);
//cout<<i<<endl;
int llen=i-l2;
int rlen=h2-i;
if(rlen>0){
root->right=createTree(a,b,h1-rlen,h1-1,h2-rlen+1,h2);
}else{
root->right=NULL;
}
if(llen>0){
root->left=createTree(a,b,l1,l1+llen-1,l2,l2+llen-1);
}else{
root->left=NULL;
}
return root;
}
void BFS(Tree* root,int n){
queue<Tree*> q;
int count=0;
q.push(root);
while(!q.empty()){
Tree* temp=q.front();
q.pop();
printf("%d",temp->data);
count<n?printf(" "):printf("\n");
if(temp->left!=NULL)q.push(temp->left);
if(temp->right!=NULL)q.push(temp->right);
}
}
int main(){
int n;
while(~scanf("%d",&n)){
int a[31],b[31];
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(int i=0;i<n;i++){
scanf("%d",&b[i]);
}
Tree* t=createTree(a,b,0,n-1,0,n-1);
BFS(t,n);
}
return 0;
} #include<iostream>
(720)#include<cstdio>
#include<stack>
(850)#include<queue>
using namespace std;
struct node{
int data;
node* left;
node* right;
node(int x):data(x),left(NULL),right(NULL){}
};
int pre[35];
int in[35];
int post[35];
node* create(int postl,int postr,int inl,int inr){
if(postl>postr){
return NULL;
}
node* root=new node(post[postr]);
int i;
for(i=inl;i<=inr;i++){
if(in[i]==post[postr])
break;
}
root->left=create(postl,postl+i-inl-1,inl,i-1);
root->right=create(postl+i-inl,postr-1,i+1,inr);
// cout<<"complete!!!"<<endl;
return root;
}
void BFS(node* root){
queue<node*> res;
res.push(root);
while(!res.empty()){
node* cur=res.front();
int temp=cur->data;
cout<<temp<<" ";
res.pop();
if(cur->left){
res.push(cur->left);
}
if(cur->right){
res.push(cur->right);
}
}
}
int main(){
int count;
cin>>count;
for(int i=0;i<count;i++){
cin>>post[i];
}
for(int i=0;i<count;i++){
cin>>in[i];
}
node* root=create(0,count-1,0,count-1);
BFS(root);
return 0;
}//幼儿园级别的代码水平,参考了算法笔记
input()
d,m,p = {},[],0
a,d[0] = input().split()[::-1],[input().split()[::-1]]
try:
while a:
for i in range(len(d[p])):
if len(d[p][i]) <= 1:continue
for j in a:
if j in d[p][i]:
a.remove(j)
break
for k in range(len(d[p][i])):
if d[p][i][k] == j:
break
try:
d[p + 1].extend([d[p][i][:k],d[p][i][1 + k:]])
except:
d[p + 1] = [d[p][i][:k],d[p][i][1 + k:]]
d[p][i] = [j]
p += 1
except:
for i in d:
try:
while True:
d[i].remove([])
except:
pass
for i in d:
for j in d[i][::-1]:
m += [j[0]]
print(' '.join(' '.join(m).split()))
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<stack>
#include<string>
#include<map>
#include<queue>
using namespace std;
int n=0;
vector<int> post;
vector<int> in;
struct node
{
int num;
struct node *left=NULL;
struct node *right=NULL;
node(int num = 0, struct node *left = NULL, struct node *right = NULL) {
this->num = num;
this->left = left;
this->right = right;
}
};
int findpos(int a) {
for (int i = 0; i < n; i++) {
if (in[i] == a) {
return i;
}
}
return 0;
}
struct node *buildtree(int lowpost, int highpost, int lowin, int highin)
{
//int pos = findpos(post[highpost]);
////cout << lowpost << ' ' << highpost << ' ' << lowin << ' ' << highin <<' '<<pos<< endl;
////getchar();
//struct node newnode = {0,NULL,NULL};
//newnode.num = post[highpost];
////cout << newnode.num << endl;
//if (lowin <= pos - 1) {
// newnode.left = buildtree(lowpost, lowpost + pos - lowin-1, lowin, pos - 1);
//}
//if (pos + 1 <= highin) {
// newnode.right = buildtree(highpost - 1 - (highin - pos-1), highpost - 1, pos + 1, highin);
//}
//cout << (int)&newnode << endl;
//cout << newnode.num<<endl;
//return &newnode;
int pos = findpos(post[highpost]);
//cout << lowpost << ' ' << highpost << ' ' << lowin << ' ' << highin <<' '<<pos<< endl;
//getchar();
struct node *newnode =new struct node;
newnode->num = post[highpost];
//cout << newnode.num << endl;
if (lowin <= pos - 1) {
newnode->left = buildtree(lowpost, lowpost + pos - lowin - 1, lowin, pos - 1);
}
if (pos + 1 <= highin) {
newnode->right = buildtree(highpost - 1 - (highin - pos - 1), highpost - 1, pos + 1, highin);
}
//cout << (int)newnode << endl;
//cout << newnode->num << endl;
return newnode;
}
int main()
{
freopen("data.txt", "r", stdin);
cin >> n;
for (int i = 0; i < n; i++) {
int a;
cin >> a;
post.push_back(a);
}
for (int i = 0; i < n; i++) {
int a;
cin >> a;
in.push_back(a);
}
freopen("CON", "r", stdin);
struct node * root;
//节点数一定大于零
root=buildtree(0, n - 1, 0, n - 1);//该子树后续开始结束,中序开始结束,返回建立好的子树的根指针
//cout << (int)root << endl;
//cout << root->num << endl;
//cout << (int)root->left << endl;
//层序遍历打印
queue<struct node*> q;
q.push(root);
bool isfirst = true;
while (q.empty() != true) {
if (isfirst == true) {
printf("%d", q.front()->num);
isfirst = false;
}
else {
printf(" %d", q.front()->num);
}
if (q.front()->left != NULL) {
q.push(q.front()->left);
}
if (q.front()->right != NULL) {
q.push(q.front()->right);
}
q.pop();
}
getchar();
return 0;
}
问一下buildtree注释部分的新节点声明有什么问题呢?
buildtree中使用new来初始化节点是可以的,直接调用构造函数却不对 class TreeNode(object): def __init__(self, data=0, left=None, right=None): self.data = data self.left = left self.right = right def parseTree(po, ino, n): if n == 0: return None idx = ino.index(po[n-1]) root = TreeNode(po[n-1]) root.left = parseTree(po[:idx], ino[:idx], idx) root.right = parseTree(po[idx:n-1], ino[idx+1:], n-idx-1) return root def levelTraverse(root): queue = []; rlt = [] queue.append(root) while queue: node = queue.pop(0) rlt.append(node.data) if node.left: queue.append(node.left) if node.right: queue.append(node.right) return rlt N = input() po = map(int, raw_input().strip().split()) ino = map(int, raw_input().strip().split()) root = parseTree(po, ino, N) rlt = levelTraverse(root) rlt = map(str, rlt) print(' '.join(rlt))