使用递归方式实现二叉树的前中后序遍历是很简单,我们只需要使用很简洁的递归语句,函数栈会自动帮我们执行复杂的操作。而使用非递归方式实现二叉树的前中后序遍历,本质上就是人为创建栈去模拟函数栈。
1. 前序遍历的非递归实现
-
申请一个栈stack,然后将头节点压入stack中。
-
从stack中弹出栈顶节点,打印,再将其右孩子节点(不为空的话)先压入stack中,最后将其左孩子节点(不为空的话)压入stack中。
-
不断重复步骤2,直到stack为空,全部过程结束。
private static void firstSearch(TreeNode t){
Stack<TreeNode> stack = new Stack<>();
// 先放根,然后pop出来放右节点和左节点,然后重复上述操作
stack.push(t);
while(!stack.isEmpty()){
TreeNode temp = stack.peek();
stack.pop();
System.out.println(temp.val);
if(temp.right != null){
stack.push(temp.right);
}
if(temp.left != null){
stack.push(temp.left);
}
}
}
2. 中序遍历的非递归实现
-
申请一个栈stack,初始时令cur=head
-
先把cur压入栈中,依次把左边界压入栈中,即不停的令t=t.left,重复步骤2
-
不断重复2,直到为null,从stack中弹出一个节点,记为node,打印node的值,并令t=node.right,重复步骤2
-
当stack为空且t为空时,整个过程停止。
private static void midSearch(TreeNode t){
Stack<TreeNode> stack = new Stack<>();
// 首先不断入栈顶节点的左节点,直到入不了为止,然后pop出栈顶节点,入一个右节点,然后入该右节点的左子节点直到
// 入不了为止,重复上述步骤
if(t != null){
while(t != null || !stack.isEmpty()){
if(t != null){
stack.push(t);
t = t.left;
}else{
System.out.println(stack.peek().val);
t = stack.pop().right;
}
}
}
}
3. 后序遍历的非递归实现
-
申请一个栈s1,然后将头节点压入栈s1中。
-
从s1中弹出的节点记为temp,然后依次将temp的左孩子节点和右孩子节点压入s1中。
-
在整个过程中,每一个从s1中弹出的节点都放进s2中。
-
不断重复步骤2和步骤3,直到s1为空,过程停止。
-
从s2中依次弹出节点并打印,打印的顺序就是后序遍历的顺序。
private static void lastSearch(TreeNode t){
// 仿照先序遍历的相反顺序,但是pop出来后需要放入另一个栈中
Stack<TreeNode> stack1 = new Stack<>();
Stack<TreeNode> stack2 = new Stack<>();
stack1.push(t);
while(!stack1.isEmpty()){
TreeNode temp = stack1.peek();
stack2.push(stack1.pop());
if(temp.left != null){
stack1.push(temp.left);
}
if(temp.right != null){
stack1.push(temp.right);
}
}
while(!stack2.isEmpty()){
System.out.println(stack2.pop().val);
}
}