LeetCode:Binary Tree Postorder Traversal

题目:非递归实现二叉树的后序遍历。题目链接

算法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)的空间要求不能使用栈,因此要先翻转路径,输出后,再恢复

比如下面的树:

LeetCode:Binary Tree Postorder Traversal

当第二次访问到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

你可能感兴趣的:(LeetCode)