题目:非递归实现二叉树的后序遍历。题目链接
算法1:非递归使用栈。首先把根节点压栈,然后循环如下操作:用一个变量来记录上次访问的节点,如果当前栈顶元素左右儿子都为空 或者 上次访问的节点非空且等于栈顶节点的左儿子或右儿子,则直接访问;否则把栈顶元素的右节点和左节点依次压栈。代码如下:
1 /** 2 * Definition for binary tree 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 vector<int> postorderTraversal(TreeNode *root) { 13 // IMPORTANT: Please reset any member data you declared, as 14 // the same Solution instance will be reused for each test case. 15 vector<int>res; 16 if(root == NULL)return res; 17 stack<TreeNode *> nstack; 18 nstack.push(root); 19 TreeNode *pre = NULL;//指向上次访问的节点 20 while(nstack.empty() == false) 21 { 22 TreeNode *p = nstack.top(); 23 if((p->left == NULL && p->right == NULL) || 24 (pre != NULL && (pre == p->left || pre == p->right))) 25 { 26 res.push_back(p->val); 27 nstack.pop(); 28 pre = p; 29 } 30 else 31 { 32 if(p->right) 33 nstack.push(p->right); 34 if(p->left) 35 nstack.push(p->left); 36 } 37 } 38 return res; 39 } 40 };
算法2:非递归不使用栈(Morris Traversal算法),只要在Morris Traversal中序遍历的算法基础上要做较大改动,它和中序morris遍历有所不同,在发现当前结点左子树为空时,不访问此结点(后序遍历需要保证访问完右子树后才能访问根结点),直接访问右子树。
第二次遍历到某个结点时,将该结点左子树的最右路径(右指针所在的路径)反序输出即可。步骤如下,代码中红色部分是修改的:
建立一个临时节点dump,令其左孩子是root,右孩子为空
当前节点设置为临时节点dump。
重复以下1、2直到当前节点为空。
1. 如果当前节点的左孩子为空,则将其右孩子作为当前节点。
2. 如果当前节点的左孩子不为空,在当前节点的左子树中找到当前节点在中序遍历下的前驱节点。
a) 如果前驱节点的右孩子为空,将它的右孩子设置为当前节点。当前节点更新为当前节点的左孩子。
b) 如果前驱节点的右孩子为当前节点,将它的右孩子重新设为空。倒序输出从当前节点的左孩子到前驱节点这条路径上的所有节点。当前节点更新为当前节点的右孩子。
注意:倒序输出路径上的节点时,由于题目O(1)的空间要求不能使用栈,因此要先翻转路径,输出后,再恢复
比如下面的树:
当第二次访问到6时,输出8,;第二次访问2时,输出9、6、4;第二次访问1时输出7、5、2,第二次访问dump节点时输出1、3
1 /** 2 * Definition for binary tree 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 vector<int> postorderTraversal(TreeNode *root) { 13 // IMPORTANT: Please reset any member data you declared, as 14 // the same Solution instance will be reused for each test case. 15 vector<int>res; 16 if(root == NULL)return res; 17 TreeNode dump(0); 18 dump.left = root; 19 TreeNode *cur = &dump, *prev = NULL; 20 while (cur) 21 { 22 if (cur->left == NULL) 23 { 24 cur = cur->right; 25 } 26 else 27 { 28 prev = cur->left; 29 while (prev->right != NULL && prev->right != cur) 30 prev = prev->right; 31 32 if (prev->right == NULL) 33 { 34 prev->right = cur; 35 cur = cur->left; 36 } 37 else 38 { 39 printReverse(cur->left, prev, res); // visit node 40 prev->right = NULL; 41 cur = cur->right; 42 } 43 } 44 } 45 return res; 46 } 47 void reverse(TreeNode *from, TreeNode *to) // reverse the tree nodes 'from' -> 'to'. 48 { 49 if (from == to) 50 return; 51 TreeNode *x = from, *y = from->right, *z; 52 do 53 { 54 z = y->right; 55 y->right = x; 56 x = y; 57 y = z; 58 }while(x != to); 59 } 60 61 void printReverse(TreeNode* from, TreeNode *to, vector<int> &res) // print the reversed tree nodes 'from' -> 'to'. 62 { 63 reverse(from, to); 64 65 TreeNode *p = to; 66 while(true) 67 { 68 res.push_back(p->val); 69 if (p == from) 70 break; 71 p = p->right; 72 } 73 74 reverse(to, from); 75 } 76 77 };
【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3416835.html