玩转二叉树
【问题描述】
给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。
【输入格式】
输入第一行给出一个正整数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
【算法思路】
递归分治法。先由中序遍历和前序序列递归构造原来的树。再递归层次输出就好了,反转只要先输出右节点,再输出左节点即可。可能有更好的解法。
【程序】
#include <iostream> #include <vector> using namespace std; struct Node { int left; int right; int value; }; int getTree(vector<Node>& nodes, int *fore, int * midd, int fs, int fe, int ms, int me){ for(int i=ms; i<=me; i++){ if(midd[i] == fore[fs]){ //left if(i==ms){ nodes[i].left = -1; }else{ nodes[i].left = getTree(nodes, fore, midd, fs+1, fs+i-ms, ms, i-1); } //right if(i==me){ nodes[i].right = -1; }else{ nodes[i].right = getTree(nodes, fore, midd, fs+i-ms+1, fe, i+1, me); } return i; } } } //用队列输出 void output(int root, vector<Node>& nodes) { int head=0, tail=0; int* seq = new int[nodes.size()]; seq[head] = root; while(head<nodes.size()){ cout<<nodes[ seq[head] ].value<<" "; if( nodes[ seq[head] ].right != -1 ){ seq[++tail] = nodes[ seq[head] ].right; } if( nodes[ seq[head] ].left != -1 ){ seq[++tail] = nodes[ seq[head] ].left; } head++; } } int main() { int num; cin>>num; int* fore = new int[num]; int* midd = new int[num]; vector<Node> nodes; Node tmp; for(int i=0; i<num; i++){ cin>>midd[i]; tmp.value = midd[i]; nodes.push_back(tmp); } for(int i=0; i<num; i++){ cin>>fore[i]; } int root = getTree(nodes, fore, midd, 0, num-1, 0, num-1); output(root, nodes); delete[] fore; delete[] midd; return 0; }