Skip to content

Commit 010bf03

Browse files
committed
binary tree pos travel
1 parent 4cae8d8 commit 010bf03

File tree

1 file changed

+153
-146
lines changed

1 file changed

+153
-146
lines changed

src/main/java/grey/algorithm/Code_0012_LeetCode_0145_BinaryTreePostorderTraversal.java

Lines changed: 153 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -7,150 +7,157 @@
77
// 笔记:https://www.cnblogs.com/greyzeng/articles/15941957.html
88
public class Code_0012_LeetCode_0145_BinaryTreePostorderTraversal {
99

10-
// 递归方法
11-
public List<Integer> postorderTraversal3(TreeNode root) {
12-
List<Integer> ans = new ArrayList<>();
13-
pos(root, ans);
14-
return ans;
15-
}
16-
17-
public void pos(TreeNode root, List<Integer> ans) {
18-
if (null != root) {
19-
pos(root.left, ans);
20-
pos(root.right, ans);
21-
ans.add(root.val);
22-
}
23-
}
24-
25-
// 非递归 双栈或者一栈+一链表方式
26-
// 改造先序遍历
27-
// 先序遍历是,头,左,右
28-
// 改造一下,变成:头,右,左
29-
// 然后:逆序一下,就变成了后序遍历
30-
// 所以用两个栈即可实现
31-
public List<Integer> postorderTraversal2(TreeNode root) {
32-
List<Integer> ans = new ArrayList<>();
33-
if (null == root) {
34-
return ans;
35-
}
36-
Stack<TreeNode> stack = new Stack<>();
37-
Stack<TreeNode> helper = new Stack<>();
38-
stack.push(root);
39-
while (!stack.isEmpty()) {
40-
TreeNode node = stack.pop();
41-
helper.push(node);
42-
if (node.left != null) {
43-
stack.push(node.left);
44-
}
45-
if (node.right != null) {
46-
stack.push(node.right);
47-
}
48-
}
49-
while (!helper.isEmpty()) {
50-
ans.add(helper.pop().val);
51-
}
52-
return ans;
53-
}
54-
55-
// TODO
56-
// 【非递归】【单栈】后序遍历
57-
public static List<Integer> postorderTraversal1(TreeNode h) {
58-
List<Integer> ans = new ArrayList<>();
59-
if (h != null) {
60-
Stack<TreeNode> stack = new Stack<>();
61-
stack.push(h);
62-
// 如果始终没有打印过节点,h就一直是头节点
63-
// 一旦打印过节点,h就变成打印节点
64-
// 之后h的含义 : 上一次打印的节点
65-
while (!stack.isEmpty()) {
66-
TreeNode cur = stack.peek();
67-
if (cur.left != null && h != cur.left && h != cur.right) {
68-
// 有左树且左树没处理过
69-
stack.push(cur.left);
70-
} else if (cur.right != null && h != cur.right) {
71-
// 有右树且右树没处理过
72-
stack.push(cur.right);
73-
} else {
74-
// 左树、右树 没有 或者 都处理过了
75-
ans.add(cur.val);
76-
h = stack.pop();
77-
}
78-
}
79-
}
80-
return ans;
81-
}
82-
83-
// morris遍历实现后序遍历
84-
// 处理时机放在能回到自己两次的点,且第二次回到自己的时刻,第二次回到他自己的时候,
85-
// 不打印他自己,而是逆序打印他左树的右边界, 整个遍历结束后,单独逆序打印整棵树的右边界
86-
public List<Integer> postorderTraversal(TreeNode root) {
87-
if (root == null) {
88-
return new ArrayList<>();
89-
}
90-
List<Integer> ans = new ArrayList<>();
91-
TreeNode cur = root;
92-
TreeNode mostRight;
93-
while (cur != null) {
94-
mostRight = cur.left;
95-
if (mostRight != null) {
96-
while (mostRight.right != null && mostRight.right != cur) {
97-
mostRight = mostRight.right;
98-
}
99-
if (mostRight.right == null) {
100-
mostRight.right = cur;
101-
cur = cur.left;
102-
continue;
103-
} else {
104-
mostRight.right = null;
105-
// 第二次来到自己的时候,收集自己的左树的右边界
106-
collect(cur.left, ans);
107-
}
108-
}
109-
cur = cur.right;
110-
}
111-
collect(root, ans);
112-
return ans;
113-
}
114-
115-
private void collect(TreeNode root, List<Integer> ans) {
116-
TreeNode node = reverse(root);
117-
TreeNode c = node;
118-
while (c != null) {
119-
ans.add(c.val);
120-
c = c.right;
121-
}
122-
reverse(node);
123-
}
124-
125-
private TreeNode reverse(TreeNode node) {
126-
TreeNode pre = null;
127-
TreeNode cur = node;
128-
while (cur != null) {
129-
TreeNode t = cur.right;
130-
cur.right = pre;
131-
pre = cur;
132-
cur = t;
133-
}
134-
return pre;
135-
}
136-
137-
public class TreeNode {
138-
139-
int val;
140-
TreeNode left;
141-
TreeNode right;
142-
143-
TreeNode() {
144-
}
145-
146-
TreeNode(int val) {
147-
this.val = val;
148-
}
149-
150-
TreeNode(int val, TreeNode left, TreeNode right) {
151-
this.val = val;
152-
this.left = left;
153-
this.right = right;
154-
}
155-
}
10+
// 递归方法
11+
public List<Integer> postorderTraversal3(TreeNode root) {
12+
List<Integer> ans = new ArrayList<>();
13+
pos(root, ans);
14+
return ans;
15+
}
16+
17+
public void pos(TreeNode root, List<Integer> ans) {
18+
if (null != root) {
19+
pos(root.left, ans);
20+
pos(root.right, ans);
21+
ans.add(root.val);
22+
}
23+
}
24+
25+
// 非递归 双栈或者一栈+一链表方式
26+
// 改造先序遍历
27+
// 先序遍历是,头,左,右
28+
// 改造一下,变成:头,右,左
29+
// 然后:逆序一下,就变成了后序遍历
30+
// 所以用两个栈即可实现
31+
public List<Integer> postorderTraversal2(TreeNode root) {
32+
List<Integer> ans = new ArrayList<>();
33+
if (null == root) {
34+
return ans;
35+
}
36+
Stack<TreeNode> stack = new Stack<>();
37+
Stack<TreeNode> helper = new Stack<>();
38+
stack.push(root);
39+
while (!stack.isEmpty()) {
40+
TreeNode node = stack.pop();
41+
helper.push(node);
42+
if (node.left != null) {
43+
stack.push(node.left);
44+
}
45+
if (node.right != null) {
46+
stack.push(node.right);
47+
}
48+
}
49+
while (!helper.isEmpty()) {
50+
ans.add(helper.pop().val);
51+
}
52+
return ans;
53+
}
54+
55+
// TODO
56+
// 【非递归】【单栈】后序遍历
57+
public static List<Integer> postorderTraversal1(TreeNode h) {
58+
// 创建一个列表用于存储后序遍历结果
59+
List<Integer> ans = new ArrayList<>();
60+
61+
// 如果根节点不为空,开始遍历
62+
if (h != null) {
63+
Stack<TreeNode> stack = new Stack<>();
64+
stack.push(h); // 将根节点压入栈
65+
66+
// h 的含义:上一次被处理(打印)的节点
67+
while (!stack.isEmpty()) {
68+
TreeNode cur = stack.peek(); // 查看栈顶节点但不弹出
69+
70+
// 如果当前节点有左子树,且左子树还没被处理过
71+
if (cur.left != null && h != cur.left && h != cur.right) {
72+
stack.push(cur.left); // 继续深入左子树
73+
}
74+
// 如果左子树处理过了,现在检查右子树是否需要处理
75+
else if (cur.right != null && h != cur.right) {
76+
stack.push(cur.right); // 继续深入右子树
77+
}
78+
// 左右子树都处理过了,可以处理当前节点
79+
else {
80+
ans.add(cur.val); // 加入结果列表
81+
h = stack.pop(); // 弹出当前节点,并标记为已处理
82+
}
83+
}
84+
}
85+
86+
// 返回后序遍历结果
87+
return ans;
88+
}
89+
90+
// morris遍历实现后序遍历
91+
// 处理时机放在能回到自己两次的点,且第二次回到自己的时刻,第二次回到他自己的时候,
92+
// 不打印他自己,而是逆序打印他左树的右边界, 整个遍历结束后,单独逆序打印整棵树的右边界
93+
public List<Integer> postorderTraversal(TreeNode root) {
94+
if (root == null) {
95+
return new ArrayList<>();
96+
}
97+
List<Integer> ans = new ArrayList<>();
98+
TreeNode cur = root;
99+
TreeNode mostRight;
100+
while (cur != null) {
101+
mostRight = cur.left;
102+
if (mostRight != null) {
103+
while (mostRight.right != null && mostRight.right != cur) {
104+
mostRight = mostRight.right;
105+
}
106+
if (mostRight.right == null) {
107+
mostRight.right = cur;
108+
cur = cur.left;
109+
continue;
110+
} else {
111+
mostRight.right = null;
112+
// 第二次来到自己的时候,收集自己的左树的右边界
113+
collect(cur.left, ans);
114+
}
115+
}
116+
cur = cur.right;
117+
}
118+
collect(root, ans);
119+
return ans;
120+
}
121+
122+
private void collect(TreeNode root, List<Integer> ans) {
123+
TreeNode node = reverse(root);
124+
TreeNode c = node;
125+
while (c != null) {
126+
ans.add(c.val);
127+
c = c.right;
128+
}
129+
reverse(node);
130+
}
131+
132+
private TreeNode reverse(TreeNode node) {
133+
TreeNode pre = null;
134+
TreeNode cur = node;
135+
while (cur != null) {
136+
TreeNode t = cur.right;
137+
cur.right = pre;
138+
pre = cur;
139+
cur = t;
140+
}
141+
return pre;
142+
}
143+
144+
public class TreeNode {
145+
146+
int val;
147+
TreeNode left;
148+
TreeNode right;
149+
150+
TreeNode() {
151+
}
152+
153+
TreeNode(int val) {
154+
this.val = val;
155+
}
156+
157+
TreeNode(int val, TreeNode left, TreeNode right) {
158+
this.val = val;
159+
this.left = left;
160+
this.right = right;
161+
}
162+
}
156163
}

0 commit comments

Comments
 (0)