二叉树的非递归遍历
先序遍历:根结点 左子树 右子树
借助一个栈。
主要步骤:
- 头结点不为null,入栈。
- 迭代条件,栈不为空。
- 弹出栈顶结点,弹出就打印
- 有右先压右,有左再压左(先压弹出结点的右结点,再压弹出结点的左结点)
代码:
public static void preOrderUnR(Node root) {
if(root == null){
return;
}
System.out.println("preOrder : ");
Stack<Node> stack = new Stack<Node>();
// 头节点入栈
stack.psuh(root);
//循环条件,栈不空
while(!stack.isEmpty()){
root = stack.pop();
// 弹出就打印
System.out.print(root.data + " ");
// 有右先压右
if(root.right != null){
stack.push(root.right);
}
// 有左再压左
if(root.left != null){
stack.add(root.left);
}
}
System.out.println();
}
中序遍历: 左子树 根结点 右子树
借助一个栈。
步骤:
- 循环条件,当前结点不为null,或者栈不为空
- 如果当前结点不为null,入栈,向左走。
- 如果当前结点为null,从栈中弹出栈顶结点,打印,向右走。
代码实现:
public static void inOrderUnR(Node root){
System.out.println("InOrder : ");
Stack<Node> stack = new Stack<Node>();
//循环条件当前结点不为null,或者栈不空
while(root != null || !stack.isEmpty()){
// 当前结点不为null,入栈,向左走
if(root != null){
stack.push(root);
root = root.left;
}else{ // root == null
// 弹出,打印,向右走
root = stack.pop();
System.out.println(root.data + " ");
root = root.right;
}
}
System.out.println();
}
后序遍历: 左子树 右子树 根结点
借助双栈。因为先序是 根 左 右,而压栈过程中是,先右后左,而如果,先压左后压右,则顺序为 根 右 左。再通过第二个栈逆序就 左 右 根 了。
主要步骤:
- 头不为null,入栈1。
- 循环条件,栈1不空。
- 弹出栈顶结点,不打印,入第二个栈。
- 有左先压左,有右后压右。
- 循环结束后,将栈2的元素弹出并打印。
代码实现:
public static void postOrderUnR(Node root){
System.out.println("PostOrder : ");
if(root != null){
// 双栈
Stack<Node> stack1 = new Stack<Node>();
Stack<Node> stack2 = new Stack<Node>();
// 头入栈1
stack1.push(root);
// 栈1不空
while(!stack1.isEmpty()){
//弹出入第二个栈
root = stack1.pop();
stack2.push(root);
//有左先压左
if(root.left != null){
stack1.push(root.left);
}
//有右后压右
if(root.right != null){
stack1.push(root.right);
}
}
// 遍历栈2
while(!stack2.isEmpty()){
root = stack2.pop();
System.out.print(root.data + " ");
}
}