二叉树的遍历有三种形式:前序遍历、中序遍历、后序遍历,三种遍历的规则分别如下:
1)前序遍历:先遍历根节点,然后遍历左子节点,最后遍历右子节点,简记为“根-左-右”;
2)中序遍历:先遍历左子节点,然后遍历根节点,最后遍历右子节点,简记为“左-根-右”;
3)后序遍历:先遍历左子节点,然后遍历右子节点,最后遍历根节点,简记为“左-右-根”;
如果记性不好的朋友,总是记错,可以这么理解,前、中、后指的都是根的遍历顺序,然后无论何种遍历,左节点都比右节点优先遍历~
其实这都是大一时候学习的东西了,想想自己大一的时候还是比较堕落,连这个都没亲手实现过,那个时候遇到了困难就容易滋生恐惧,导致现在对数据结构算法都还心存阴影。这是一个不可以原谅的错误!回不到过去,只是在现在的时间加倍的补回来。只有与恶龙缠斗才能享受斩杀其瞬间的快感,只有直面自己内心的深渊,才能够找到光明。没有困难是克服不了的!
话不多说,开始上代码。我们先尝试用递归实现:
/**
* 定义节点类
* @author Keo.Zhao
*
*/
public class TreeNode<T> {
public T data;
public TreeNode<T> left;
public TreeNode<T> right;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public TreeNode<T> getLeft() {
return left;
}
public void setLeft(TreeNode<T> left) {
this.left = left;
}
public TreeNode<T> getRight() {
return right;
}
public void setRight(TreeNode<T> right) {
this.right = right;
}
public TreeNode(T data, TreeNode<T> left, TreeNode<T> right) {
this.data = data;
this.left = left;
this.right = right;
}
}
然后我们定义一颗二叉树,其中包含了遍历的方法:
/**
* 二叉树定义类
* @author Keo.Zhao
*
* @param <T>
*/
public class BinTree<T> {
private TreeNode<T> root;
public BinTree(TreeNode<T> root) {
this.root = root;
}
public TreeNode<T> getRoot() {
return root;
}
public void setRoot(TreeNode<T> root) {
this.root = root;
}
/**
* 递归先序遍历
*/
public void preOrder(TreeNode<T> root){
if(root != null){
System.out.print(root.data + " ");
preOrder(root.left);
preOrder(root.right);
}
}
/**
* 递归中序遍历
*/
public void midOrder(TreeNode<T> root){
if(root != null){
preOrder(root.left);
System.out.println(root.data + " ");
preOrder(root.right);
}
}
/**
* 递归后序遍历
*/
public void afterOrder(TreeNode<T> root){
if(root != null){
preOrder(root.left);
preOrder(root.right);
System.out.println(root.data + " ");
}
}
}
递归的思想比较简单,代码也比较简洁,但是实际开发中最好还是不要用递归。所以我们可以尝试,用
迭代的思想去实现。
这里用到了Stack,栈是Vector的一个子类,它实现了一个标准的后进先出的栈。
堆栈只定义了默认构造函数,用来创建一个空栈。 堆栈除了包括由Vector定义的所有方法,也定义了自己的一些方法。
在使用迭代的方式遍历的过程中,需要维护一个栈用来保存遍历的节点信息,相应代码如下所示:
/**
* 非递归的前序遍历实现
* @param root
*/
public void iterativePreorder(TreeNode<T> root){
if(root == null){
return;
}
Stack<TreeNode<T>> stack = new Stack<TreeNode<T>>();
stack.push(root);
while(!stack.isEmpty()){
while(stack.peek() != null){
System.out.print(stack.peek().data + " ");
stack.push(stack.peek().left);
}
TreeNode<T> p= stack.pop();
if(!stack.isEmpty()){
p = stack.pop();
stack.push(p.right);
}
}