题目链接 :http://www.patest.cn/contests/pat-a-practise/1086
这道题之前用idx做过一遍,今天用iterator做了一遍,果然C++的iterator还是觉得别扭,但感觉比以前好多了。
从题目给的数据中能够知道该树的前序遍历和中序遍历的结果,push过程的顺序是前序遍历,pop出来的内容逐个取出是中序遍历。然后再递归得到后序遍历的结果。递归的过程也即从前序遍历拿出第一个元素,在中序中找到,求出left和right的大小,再进行下面的递归。
代码:
1 #include <fstream> 2 #include <vector> 3 #include <iostream> 4 #include <stack> 5 #include <string> 6 #include <algorithm> 7 8 using namespace std; 9 10 //#define OJ 11 #ifdef OJ 12 #define fin cin 13 #else 14 ifstream fin("in.txt"); 15 #endif 16 17 vector<int> pre_order; 18 vector<int> in_order; 19 vector<int> post_order; 20 int n; 21 22 typedef vector<int>::iterator iter_type; 23 24 void solve(iter_type pre_begin, iter_type pre_end, iter_type in_begin, iter_type in_end, iter_type post_begin, iter_type post_end){ 25 if (pre_begin == pre_end) 26 return; 27 28 iter_type mid_iter; 29 for (mid_iter = in_begin; mid_iter != in_end; mid_iter++) 30 if (*mid_iter == *pre_begin) 31 break; 32 int left = distance(in_begin, mid_iter); 33 int right = distance(next(mid_iter), in_end); 34 *prev(post_end) = *mid_iter; 35 36 if (left > 0) 37 solve(next(pre_begin), next(pre_begin, left + 1), in_begin, mid_iter, post_begin, next(post_begin, left)); 38 if (right > 0) 39 solve(prev(pre_end, right), pre_end, next(mid_iter), in_end, next(post_begin, left), prev(post_end)); 40 } 41 42 int main(){ 43 string str; 44 fin >> n; 45 46 getline(fin, str); 47 48 pre_order.reserve(n); 49 in_order.reserve(n); 50 post_order.resize(n); 51 stack<int> s; 52 while (getline(fin, str)){ 53 if (str.size() == 3){ 54 in_order.push_back(s.top()); 55 s.pop(); 56 } 57 else { 58 int tmp = atoi(str.substr(5, str.size() - 5).c_str()); 59 pre_order.push_back(tmp); 60 s.push(tmp); 61 } 62 } 63 64 solve(pre_order.begin(), pre_order.end(), in_order.begin(), in_order.end(), post_order.begin(), post_order.end()); 65 cout << post_order[0]; 66 for (iter_type it = next(post_order.begin()); it != post_order.end(); it++){ 67 cout << " " << *it; 68 } 69 cout << endl; 70 71 return 0; 72 }