166 lines
3.7 KiB
C++
166 lines
3.7 KiB
C++
// 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;
|
|
}
|