对于我来说,传统的二叉树三序遍历的递归写法统一了模板,简短易理解;但非递归写法经常一看就会,一写就废,反反复复的复习感觉特别麻烦,在leetcode刷题时偶然看到了这个大佬的题解,颜色标记法,大佬是用python实现的,我按照大佬的思想写出了Java实现,并且改进了一下大佬的写法,有兴趣的朋友们也可以按照这个思想写出c++,js等版本的解法!
颜色标记法的思想:
①访问过的节点标记为白色,未访问的节点标记为灰色。
②取出栈顶元素时,判断是哪个颜色,灰色则输出,白色则按遍历方式与左右孩子压入栈。
改进版:
①因为大多数情况,节点类型是TreeNode,数据类型一般不为TreeNode,这里题目的数据类型是int,于是可以用类型判断来替代颜色标记,即从栈中取出栈顶元素,类型是TreeNode则按白色节点处理,类型是数据类型则按灰色节点处理。
②栈的泛型为Object,这样就可以存储不同类型的元素。
以下是我的代码模板。
---------------------------------------------------------------------------------------------------------------------------------
前序
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
List stack<Object> = new ArrayList<>();
stack.add(root);
while(stack.size() != 0){
Object top = stack.remove(stack.size()-1); //栈顶元素
if(top instanceof TreeNode){ // 编译器会判断左边的对象能否转化为右边的类型
TreeNode node = (TreeNode) top;
stack.add(node.right); // 只需交换这三句话的顺序,就可实现前序,中序,后序
stack.add(node.left);
stack.add(node.val); // 按栈先进后出的特点,这里的顺序是中左右
}else if(top instanceof Integer){
res.add((Integer)top);
}
}
return res;
}
}
可以在leetcode上测试这段代码
---------------------------------------------------------------------------------------------------------------------------------
中序
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
List stack = new ArrayList<>();
stack.add(root);
while(stack.size() != 0){
Object top = stack.remove(stack.size()-1); //栈顶元素
if(top instanceof TreeNode){ // 编译器会判断左边的对象能否转化为右边的类型
TreeNode node = (TreeNode) top;
stack.add(node.right);
stack.add(node.val); //按栈先进后出的特点,这里的顺序是左中右
stack.add(node.left);
}else if(top instanceof Integer){
res.add((Integer)top);
}
}
return res;
}
}
可以在leetcode上测试这段代码
---------------------------------------------------------------------------------------------------------------------------------
后序
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
List stack = new ArrayList<>();
stack.add(root);
while(stack.size() != 0){
Object top = stack.remove(stack.size()-1); //栈顶元素
if(top instanceof TreeNode){ // 编译器会判断左边的对象能否转化为右边的类型
TreeNode node = (TreeNode) top;
stack.add(node.val); //按栈先进后出的特点,这里的顺序是左右中
stack.add(node.right);
stack.add(node.left);
}else if(top instanceof Integer){
res.add((Integer)top);
}
}
return res;
}
}
可以在leetcode上测试这段代码