本文学习上文提到的二叉树实现的第二个方法:建立二叉树类。
首先补一个知识点:前面我们用递归实现了遍历,那么我们是否能用非递归结构实现遍历呢?答案是:可以的。在递归学习中我们知道转换的方法通常有两种,都要用到堆栈,因此,即便是不分析遍历特点我们也知道是堆栈。
分析:前序遍历中,在所有未被访问的结点中,已访问的结点中最后访问(输出)结点的左子树的根结点将最先被访问,因此堆栈设计如下:
(1)初始化堆栈;
(2)根结点入栈;
(3)堆栈非空时:a、出栈取栈顶结点,访问(输出)该结点;b、若右孩子非空,入栈;c、若左孩子非空,入栈;
(4)结束;
该算法和层序遍历算法结构非常类似,可以一起记忆学习,其算法代码如下(使用时要加入Traverse类中):
public static void preOrderNoRecur(BiTreeNode root)throws Exception{
LinStack s = new LinStack();//创建链式堆栈
if(root==null) return;
BiTreeNode curr;
s.push(root);//根结点入栈
while(!s.isEmpty()){
curr = (BiTreeNode)s.pop();
System.out.print(" "+curr.data);
if(curr.getRight()!=null)
s.push(curr.getRight());
if(curr.getLeft()!=null)
s.push(curr.getLeft());
}
}
接着说建立二叉树类来实现二叉树设计,代码如下:
package Tree;
/**
* @author sun
* 创建时间:2017年4月24日上午9:13:29
*/
//在二叉树结点类的基础上设计二叉树类
public class BiTree {
private BiTreeNode root;//根“指针”
private void preOrder(BiTreeNode t,Visit vs){
//前序遍历二叉树t,访问结点操作为vs.print(t.data)
if(t!=null){
vs.print(t.data);
preOrder(t.getLeft(),vs);
preOrder(t.getRight(),vs);
}
}
private void inOrder(BiTreeNode t,Visit vs){
//中序遍历二叉树t
if(t!=null){
inOrder(t.getLeft(),vs);
vs.print(t.data);
inOrder(t.getRight(),vs);
}
}
private void postOrder(BiTreeNode t,Visit vs){
//后序遍历二叉树t
if(t!=null){
postOrder(t.getLeft(),vs);
postOrder(t.getRight(),vs);
vs.print(t.data);
}
}
BiTree(){
root = null;
}
BiTree(Object item,BiTree left,BiTree right){
BiTreeNode l,r;
if(left==null) l = null;
else l = left.root;
if(right==null) r = null;
else r = right.root;
root = new BiTreeNode(item,l,r);
}
public void preOrder(Visit vs){
preOrder(root,vs);
}
public void inOrder(Visit vs){
inOrder(root,vs);
}
public void postOrder(Visit vs){
postOrder(root,vs);
}
}
主函数测试:package Tree;
/**
* @author sun
* 创建时间:2017年4月24日上午9:26:17
*/
public class TestBiTree {
public static void main(String[] args) {
BiTree g = new BiTree(new Character('G'),null,null);
BiTree d = new BiTree(new Character('D'),null,g);
BiTree b = new BiTree(new Character('B'),d,null);
BiTree e = new BiTree(new Character('E'),null,null);
BiTree f = new BiTree(new Character('F'),null,null);
BiTree c = new BiTree(new Character('C'),e,f);
BiTree a = new BiTree(new Character('A'),b,c);
Visit vs = new Visit();
System.out.print("前序遍历结点序列为:");
a.preOrder(vs);
System.out.println();
System.out.print("中序遍历结点序列为:");
a.inOrder(vs);
System.out.println();
System.out.print("后序遍历结点序列为:");
a.postOrder(vs);
System.out.println();
}
}
/*
前序遍历结点序列为:A B D G C E F
中序遍历结点序列为:D G B A E C F
后序遍历结点序列为:G D B E F C A
*/