递归的方式
二叉树的基本结构
public class Node{
public int value;
public Node left;
public Node right;
public Node(int data){
this.value=value;
}
}
二叉树的先序,中序,后序递归遍历
//先序递归遍历
public void preOrderRecur(Node head){
if(head==null) return ;
System.out.println(head.value);
preOrderRecur(head.left);
preOrderRecur(head.right);
}
//中序递归遍历
public void inOrderRecur(Node head){
if(head==null) return ;
inOrderRecur(head.left);
System.out.println(head.value);
inOrderRecur(head.right);
}
//后序遍历
public void postOrderRecur(Node head){
if(head==null) return ;
postOrderRecur(head.left);
postOrderRecur(head.right);
System.out.println(head);
}
非递归的方式
先序非递归方式
基本步骤
- 申请一个栈,记为stack,然后将头结点压入栈中
- 从stack弹出栈顶节点,记为cur,打印cur节点的值,如果cur的右孩子(不为空)先压入栈中,最后cur的左孩子压入栈中(不为空)
- 不断重复步骤2,直到栈为空
代码
//head节点相当于cur节点
public void preOrderUnRecur(Node head){
System.out.println("pre-order");
if(head==null) return;
Stack<Node> stack=new Stack<>();
Stack.push(head);
while(!stack.isEmpty()){
head=stack.pop();
System.out.println(head.value+" ");
if(head.right!=null) stack.push(head.right);
if(head.left!=null) stach.push(head.left);
}
}
中序非递归遍历方式
基本步骤
- 申请一个栈,记为stack,初始时令变量cur=head;
- 先把cur压入栈中,对以cur节点为头的整颗子树来说,依次将左边界压入栈中,即cur=cur.left,重复步骤2
- 不停重复步骤2, 直到cur=null,此时弹出节点Node.令cur=node.right,重复步骤2
- 当stack为空时并且cur=null时,整个过程停止
代码
//head节点相当于cur节点
public void inOrderUnRecur(Node head){
System.out.println("in-order");
if(head==null) return ;
Stack<Node> stack=new Stack<>();
Stack.push(head);
while(!stack.isEmpty()||head!=null){
if(head==null)
{
head=stack.pop();
System.out.println(head.value+" ");
head=head.right;
}else
{
head=head.left;
stack.push(head);
}
}
}
后序非递归遍历方式1(two stack)
基本步骤
- 申请一个栈,记为s1,,然后将头节点压入s1中
- 从s1中弹出栈顶节点,记为cur,依次将cur的左孩子与右孩子压入s1
- 申请另外一个栈s2,每次从s1弹出的栈都进入s2中
- 不断重复步骤2,3,直到栈s1为空
- 从s2依次弹出节点并打印,打印的顺序就是后序遍历的顺序
代码
//head节点相当于cur节点
public void postOrderUnRecur(Node head){
if(head==null) return ;
Stack<Node> s1=new Stack<>();
Stack<Node> s2=new Stack<>();
s1.push(head);
while(!s1.isEmpty()){
head=s1.pop();
s2.push(head);
if(head.left!=null) s1.push(head.left);
if(head.right!=null) s1.push(head.right);
}
while(!s2.isEmpty()){
System.out.println(s2.pop().value+" ");
}
}
后序非递归遍历方式2(one stack)
基本步骤
- 申请一个栈,记为s1.将头节点head压入栈中,设置两个变量c,h;c表示当前栈顶元素,h表示上一次弹出节点,初始化时c=null,h=head;
- 每次令c等于当前栈顶元素,但是不从stack弹出,此时分为三种情况:
- c.left不为空,但是h既不是c的左孩子,也不是c的右孩子;此时说明c的左孩子还没有进行处理,此时压入c的左孩子
- 1的条件不成立时,c.right不为空,并且h不为c.right,说明c的右孩子还没有处理
- 1,2都不成立时,弹出节点c并打印,此时说明c的左孩子与右孩子已经处理过了。
- 一直重复步骤2, 直到栈为null
实现
//h相当于head节点,
public void postOrderUnRecur(Node head){
if(head==null) return ;
Stack<Node> stack=new Stack<>();
Node c=null;
stack.push(head);
while(!stack.isEmpty()){
c=stack.peek();
if(c.left!=null&&head!=c.left
&&head!=c.right)
{
stack.push(c.left);
}else if(c.right!=null&&head!=c.right)
{
stack.push(c.right);
}else{
System.out.println(stack.pop().value+" ");
head=c;
}
}
}