// Source : https://oj.leetcode.com/problems/binary-tree-postorder-traversal/ // Author : Hao Chen // Date : 2014-07-21 /********************************************************************************** * * Given a binary tree, return the postorder traversal of its nodes' values. * * For example: * Given binary tree {1,#,2,3}, * * 1 * \ * 2 * / * 3 * * return [3,2,1]. * * Note: Recursive solution is trivial, could you do it iteratively? * **********************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <time.h> #include <iostream> #include <vector> #include <algorithm> using namespace std; struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; vector<int> postorderTraversal1(TreeNode *root); vector<int> postorderTraversal2(TreeNode *root); // We have two methods here. // 1) the first one acutally is pre-order but reversed the access order. // 2) the second one is the traditional one vector<int> postorderTraversal(TreeNode *root) { if (random()%2){ cout << "---method one---" << endl; return postorderTraversal1(root); } cout << "---method two---" << endl; return postorderTraversal2(root); } vector<int> postorderTraversal1(TreeNode *root) { vector<int> v; vector<TreeNode*> stack; if (root) { stack.push_back(root); } while (stack.size()>0){ TreeNode *n = stack.back(); stack.pop_back(); v.push_back(n->val); if (n->left){ stack.push_back(n->left); } if (n->right) { stack.push_back(n->right); } } std::reverse(v.begin(), v.end()); // the trick return v; } // traditional and standard way. // using the stack to simulate the recursive function stack. vector<int> postorderTraversal2(TreeNode *root) { vector<int> v; vector<TreeNode*> stack; TreeNode *node = root; TreeNode *lastVisitNode = NULL; while(stack.size()>0 || node!=NULL){ if (node != NULL){ // keep going the left stack.push_back(node); node = node->left; }else{ TreeNode *n = stack.back(); // left way is finsised, keep going to the right way if (n->right != NULL && lastVisitNode != n->right){ node = n->right; }else{ // both left and right has been accessed. stack.pop_back(); v.push_back(n->val); lastVisitNode = n; } } } return v; } TreeNode* createTree(int a[], int n) { if (n<=0) return NULL; TreeNode **tree = new TreeNode*[n]; for(int i=0; i<n; i++) { if (a[i]==0 ){ tree[i] = NULL; continue; } tree[i] = new TreeNode(a[i]); } int pos=1; for(int i=0; i<n && pos<n; i++) { if (tree[i]){ tree[i]->left = tree[pos++]; if (pos<n){ tree[i]->right = tree[pos++]; } } } return tree[0]; } void printTree_post_order(TreeNode *root) { if (root == NULL){ //cout << "# "; return ; } printTree_post_order(root->left); printTree_post_order(root->right); cout << root->val << " "; } void printArray(vector<int> v) { for(int i=0; i<v.size(); i++){ cout << v[i] << " "; } cout << endl; } int main() { srand(time(0)); int a[] = {1,2,3,4,5,0,6,0,0,7,8,9,0}; TreeNode* p = createTree(a, sizeof(a)/sizeof(int)); printTree_post_order(p); cout << endl; vector<int> v = postorderTraversal(p); printArray(v); cout << endl; return 0; }