简介
对于二叉树来讲最主要、最基本的运算是遍历。
遍历二叉树:是指以一定的次序访问二叉树中的每个结点。所谓访问结点 是指对结点进行各种操作的简称。例如,查询结点数据域的内容,或输出它的值,或找出结点位置,或是执行对结点的其他操作。遍历二叉树的过程实质是把二叉树的结点进行线性排列的过程。假设遍历二叉树时访问结点的操作就是输出结点数据域的值,那么遍历的结果得到一个线性序列。
遍历规则
从二叉树的递归定义可知,一棵非空的二叉树由根结点及左、右子树这三个基本部分组成。因此,在任一给定结点上,可以按某种次序执行三个操作:
(1)访问结点本身(N),
(2)遍历该结点的左子树(L),
(3)遍历该结点的右子树(R)。
以上三种操作有六种执行次序:
NLR(前序遍历–根左右)
LNR(中序遍历–左根右)
LRN(后序遍历–左右根)
NRL、RNL、RLN
注意:
前三种次序与后三种次序对称,故只讨论先左后右的前三种次序。
由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtlee)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。
递归遍历代码
package test.node;
public class Node {
private Node left;
private Node right;
private int value;
public Node(int value){
this.value = value;
}
public Node(){}
//前序遍历------根左右
public static void preTraversal(Node node){
if(node != null){
System.out.print(node.value);
preTraversal(node.left);
preTraversal(node.right);
}
}
//中序遍历------左根右
public static void midTraversal(Node node){
if(node != null){
midTraversal(node.left);
System.out.print(node.value);
midTraversal(node.right);
}
}
//后序遍历------左右根
public static void behTraversal(Node node){
if(node != null){
behTraversal(node.left);
behTraversal(node.right);
System.out.print(node.value);
}
}
public static void main(String[] args) {
Node n1 = new Node(1);
Node n2 = new Node(2);
Node n3 = new Node(3);
Node n4 = new Node(4);
Node n5 = new Node(5);
Node n6 = new Node(6);
Node n7 = new Node(7);
Node n8 = new Node(8);
Node n0 = null;
n1.left = n2;
n1.right = n3;
n2.left = n4;
n2.right = n5;
n5.right = n8;
n3.left = n6;
n6.right = n7;
System.out.print("前序遍历结果为:");
preTraversal(n1);
System.out.println();
System.out.print("中序遍历结果为:");
midTraversal(n1);
System.out.println();
System.out.print("后序遍历结果为:");
behTraversal(n1);
}
}
递归遍历
//前序遍历------根左右
public static void preTraversal(Node node){
if(node != null){
System.out.print(node.value);
preTraversal(node.left);
preTraversal(node.right);
}
}
//中序遍历------左根右
public static void midTraversal(Node node){
if(node != null){
midTraversal(node.left);
System.out.print(node.value);
midTraversal(node.right);
}
}
//后序遍历------左右根
public static void behTraversal(Node node){
if(node != null){
behTraversal(node.left);
behTraversal(node.right);
System.out.print(node.value);
}
}
非递归遍历
1、前序遍历
根据前序遍历访问的顺序,优先访问根结点,然后再分别访问左孩子和右孩子。即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,再访问它的右子树。因此其处理过程如下:
对于任一结点P:
1)访问结点P,并将结点P入栈;
2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P;
3)直到P为NULL并且栈为空,则遍历结束。
//先序遍历---非递归
public static void noRecPreOrder(Node node) {
System.out.print("二叉树非递归先序遍历:");
LinkedList<Node> stack = new LinkedList<Node>();
Node current = node;
while (current != null || !stack.isEmpty()) {
while (current != null) {
System.out.print(current.value);// 先序
stack.push(current);// 压入栈顶
current = current.left;
}
if (!stack.isEmpty()) {
current = stack.pop();// 移除栈顶对象,并返回该对象
// System.out.print(current.value);//中序
current = current.right;
// System.out.print(current.value);//后序
}
}
System.out.println();
}
参考:
二叉树的遍历 递归非递归 思路和 java实现http://blog.youkuaiyun.com/clam_clam/article/details/6845399