1. 程式人生 > >ACM天梯賽 L2-011. 玩轉二叉樹

ACM天梯賽 L2-011. 玩轉二叉樹

給定一棵二叉樹的中序遍歷和前序遍歷,請你先將樹做個鏡面反轉,再輸出反轉後的層序遍歷的序列。所謂鏡面反轉,是指將所有非葉結點的左右孩子對換。這裡假設鍵值都是互不相等的正整數。

輸入格式:

輸入第一行給出一個正整數N(<=30),是二叉樹中結點的個數。第二行給出其中序遍歷序列。第三行給出其前序遍歷序列。數字間以空格分隔。

輸出格式:

在一行中輸出該樹反轉後的層序遍歷的序列。數字間以1個空格分隔,行首尾不得有多餘空格。

輸入樣例:
7
1 2 3 4 5 6 7
4 1 3 2 6 5 7
輸出樣例:

4 6 1 7 5 3 2

思路。用連結串列建樹。

因為知道了前序遍歷和中序遍歷,那麼可以知道前序遍歷的第一個數就是根,然後可以在中序遍歷中找到該根的位置,然後可以分開左子樹和右子樹,然後重複這種做法,知道建樹結束。

不說了,上程式碼加註釋。

//https://www.patest.cn/contests/gplt/L2-011
//L2-011. 玩轉二叉樹
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;
bool fist;
const int maxn=40;
struct tree_node
{
  int value;
  tree_node* leftchild;
  tree_node* rightchild;
  tree_node()
  {
    leftchild=NULL
; rightchild=NULL; } }; tree_node* build_tree(int pre[],int in[],int length) { if(length==0)return NULL;//終止條件 tree_node* temp = new tree_node; int pos; for(pos=0;pos<length;pos++)//找到根節點->然後根據中序遍歷把左子樹和右子樹分開 { if(in[pos]==pre[0])break; } temp->value=pre[0]; temp->leftchild=build_tree(pre+1
,in,pos); temp->rightchild=build_tree(pre+pos+1,in+pos+1,length-pos-1); return temp; } void dfs(tree_node* tree) { queue<tree_node*>Q; while(!Q.empty())Q.pop(); Q.push(tree); tree_node* root; while(!Q.empty()) { root=Q.front(); Q.pop(); if(!fist) { cout<<root->value; fist=true; } else cout<<""<<root->value; if(root->rightchild!=NULL) { tree_node* rchild=root->rightchild; Q.push(rchild); } if(root->leftchild!=NULL) { tree_node* lchild=root->leftchild; Q.push(lchild); } } cout<<endl; } int main() { int n; int pre[maxn],in[maxn]; while(scanf("%d",&n)==1) { fist=false; //input for(int i=0;i<n;i++)scanf("%d",&in[i]); for(int i=0;i<n;i++)scanf("%d",&pre[i]); //solve tree_node* tree=build_tree(pre,in,n); dfs(tree); } }