二叉树的遍历
二叉树的遍历分为前序遍历、中序遍历、后序遍历,如果用递归实现则相当简单 ,几条语句就可以完成遍历,相比之下,非递归则稍微有点难度。下面简单介绍一下二叉树的非递归遍历
1.前序遍历:
方法:
(1)访问节点p,将p入栈
(2)如果p为空,则栈顶元素出栈,将栈顶元素的又孩子设置为当前节点p,重复(1),如果p不为空,则将p的左孩子设置为当前节点p
(3)直到p为空并且栈为空的时候结束遍历
代码如下:
public static void showPre1(Node node){
if(node==null)return;
Stack<Node> stack=new Stack<Node>();
Node p=node;
while(!stack.isEmpty()||p!=null){
while(p!=null){
System.out.print(p.value+" ");
stack.push(p);
p=p.l_node;
}
if(!stack.isEmpty()){
p=stack.peek();
stack.pop();
p=p.r_node;
}
}
}
2.中序遍历
方法:
(1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;
(2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;
(3)直到P为NULL并且栈为空则遍历结束
代码如下:
public static void showMid1(Node node){
Stack<Node> stack=new Stack<Node>();
Node p=node;
while(!stack.isEmpty()||p!=null){
while(p!=null){
stack.push(p);
p=p.l_node;
}
if(!stack.isEmpty()){
p=stack.peek();
System.out.print(p.value+" ");
stack.pop();
p=p.r_node;
}
}
}
3.后序遍历
后序遍历会稍微麻烦一点,因为之后左右孩子都访问完才能读取读取父节点
方法如下:
对于任一结点P,要先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
代码:
public static void showPost(Node node){
Node p=null;
Node pre=null;
Stack<Node> stack=new Stack<Node>();
stack.push(node);
while(!stack.isEmpty()){
p=stack.peek();
if((p.l_node==null&&p.r_node==null)||(pre!=null&&pre==p.l_node||pre==p.r_node)){
stack.pop();
System.out.print(p.value+" ");
pre=p;
}else{
if(p.r_node!=null){
stack.push(p.r_node);
}
if(p.l_node!=null){
stack.push(p.l_node);
}
}
}
}