从根结点开始,将所有最左结点全部压栈,每当一个结点出栈时,都先扫描该结点的右子树,只有当一个结点的左孩子和右孩子结点均被访问过了,才能访问结点自身。
非递归算法实现如下:
struct TreeNode { int val; TreeNode *left; TreeNode * right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; vector<int> postorderTraversal(TreeNode* root) { vector<int> path; stack<TreeNode *> st; TreeNode * pre = NULL; bool leftTag; do { //root及其所有的左子树全部入栈 while (root != NULL) { st.push(root); root = root->left; } leftTag = true; // leftTag = ture, 说明左子树为NULL或者已经全部被访问 pre = NULL; // while (!st.empty() && leftTag) { root = st.top(); if (root->right == pre) { //访问栈顶元素 path.push_back(root->val); //出栈 st.pop(); pre = root; } else { leftTag = false; root = root->right; } } } while (!st.empty()); return path; }
后序非递归算法的特性是:就是当访问某个结点时,栈中所保存的元素
正好是这个结点的所有祖先。那么知道了这个特性,我们就很容易解决下面如下问题:
(1).当给定一个叶子结点,要求输出该叶子结点的所有祖先
(2).输出根结点到所有叶子结点的路径
(3).如果二叉树结点的值是数值,那么求每条路径上值之和,也可以利用二叉树后序遍历的非递归算法这个特性