实践过的同学,也会发现使用迭代法实现先中后序遍历,很难写出统一的代码,不像是递归法,实现了其中的一种遍历方式,其他两种只要稍稍改一下节点顺序就可以了。其实针对三种遍历方式,使用迭代法是可以写出统一风格的代码!重头戏来了,接下来介绍一下统一写法。
以中序遍历为例
中序遍历:(leetcode 94 题)
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
Stack<TreeNode> st = new Stack<>();
st.push(root);
while (!st.isEmpty()) {
TreeNode cur = st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
if (cur != null) {
if (cur.right != null) {
st.push(cur.right); // 添加右节点(空节点不入栈)
}
st.push(cur); // 添加中节点
st.push(null); // 中节点访问过,但是还没有处理,加入空节点做为标记。
if (cur.left != null) {
st.push(cur.left); // 添加左节点(空节点不入栈)
}
}
else { // 只有遇到空节点的时候,才将下一个节点放进结果集
TreeNode node = st.pop(); // 重新取出栈中元素
res.add(node.val);
}
}
return res; // 加入到结果集
}
}
那么前序遍历写出来之后,中序和后序遍历就不难理解了,代码如下:
前序遍历:(leetcode 144 题)注意此时我们和中序遍历相比仅仅改变了两行代码的顺序
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
Stack<TreeNode> st = new Stack<>();
st.push(root);
while (!st.isEmpty()) {
TreeNode cur = st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
if (cur != null) {
if (cur.right != null) {
st.push(cur.right); // 添加右节点(空节点不入栈)
}
if (cur.left != null) {
st.push(cur.left); // 添加左节点(空节点不入栈)
}
st.push(cur); // 添加中节点
st.push(null); // 中节点访问过,但是还没有处理,加入空节点做为标记。
}
else { // 只有遇到空节点的时候,才将下一个节点放进结果集
TreeNode node = st.pop(); // 重新取出栈中元素
res.add(node.val);
}
}
return res; // 加入到结果集
}
}
后序遍历:(leetcode 145 题)注意此时我们和中序遍历相比仅仅改变了两行代码的顺序
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
Stack<TreeNode> st = new Stack<>();
st.push(root);
while (!st.isEmpty()) {
TreeNode cur = st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
if (cur != null) {
st.push(cur); // 添加中节点
st.push(null); // 中节点访问过,但是还没有处理,加入空节点做为标记。
if (cur.right != null) {
st.push(cur.right); // 添加右节点(空节点不入栈)
}
if (cur.left != null) {
st.push(cur.left); // 添加左节点(空节点不入栈)
}
}
else { // 只有遇到空节点的时候,才将下一个节点放进结果集
TreeNode node = st.pop(); // 重新取出栈中元素
res.add(node.val);
}
}
return res; // 加入到结果集
}
}