随意随想

知其然,知其所以然

0%

树的迭代遍历

树的深度遍历有中序遍历,前序遍历,后续遍历,在用递归的方式实现,过于简单,那么假如使用迭代的方式,也一样简单吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
* 前序遍历
* 中、左、右
* 由于遍历顺序与元素的操作顺序一致,所以可以简单的使用栈来实现
*/
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
//栈不为空
while (!stack.isEmpty()) {
TreeNode pop = stack.pop();
if (pop != null) {
result.add(pop.val);
stack.push(pop.rigth);
stack.push(pop.left);//栈的结构,后入先出
}
}
return result;
}

/**
* 后续遍历
* 左、右、中
* 后续遍历就是 前序遍历的,左右对调,然后结果集翻转
*/
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
//栈不为空
while (!stack.isEmpty()) {
TreeNode pop = stack.pop();
if (pop != null) {
result.add(pop.val);
stack.push(pop.rigth);
stack.push(pop.left);
}
}
//此时数组中的元素 应该是 中,右、 左
reverse(result);
//翻转之后,结果应该是 左、右、中
return result;
}

public static void reverse(List<Integer> result) {
int l = 0;
int r = result.size() - 1;
while (l < r) {
int temp = result.get(l);
result.set(l, result.get(r));
result.set(r, temp);
l++;
r--;
}
}

/**
* 中序遍历
* 左、中、右
* 中序遍历跟前后序遍历都不一样,主要是因为遍历的时候顺序跟元素操作的顺序不一致导致的
* 可以思考如下图的中序遍历
* 5
* / \
* 4 6
* / \
* 1 2
*/
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null) {
return result;
}
Stack<TreeNode> st = new Stack<>();
TreeNode cur = root;
while (cur != null || !st.isEmpty()) {
//当前元素不为空,继续插入左侧元素
if (cur != null) {
st.push(cur);
cur = cur.left;
} else {
//如果为空,输出栈里面的元素
TreeNode pop = st.pop();
result.add(pop.val);//当前元素是栈顶元素的左子树
cur = cur.rigth;
}
}
return result;

}