数据结构5——二叉树(1)

1:二叉树的建立

二叉树的建立有两种模式:(1):首先设计二叉树的结点类,然后在此基础上,用static成员函数实现二叉树的具体操作。

            (2):设计二叉树的结点类,然后在二叉树的结点类的基础上设计二叉树类。

 1 /*
 2  * 定义一个二叉树的结点类
 3  */
 4 public class BinTreeNode {
 5     private BinTreeNode leftChild;
 6     private BinTreeNode rightChild;
 7     private Object data;
 8     
 9     public BinTreeNode(){
10         leftChild=null;
11         rightChild=null;
12     }
13     
14     public BinTreeNode(BinTreeNode left, BinTreeNode right,Object Idata){
15         leftChild=left;
16         rightChild=right;
17         data=Idata;
18     }
19 
20     public BinTreeNode getLeftChild() {
21         return leftChild;
22     }
23 
24     public BinTreeNode getRightChild() {
25         return rightChild;
26     }
27 
28     public Object getData() {
29         return data;
30     }
31 }

设计完了二叉树的结点类之后,在二叉树的结点类的基础上用static成员函数实现二叉树的具体操作。

包括二叉树的生成,二叉树的打印二叉树的遍历,在二叉树中查找元素。

(1)首先在二叉树结点类的基础上构建二叉树。结构如上图所示:

先构造一个方法用于获得二叉树的结点类

//获得一个二叉树结点的类
    public static BinTreeNode getTreeNode(Object item, BinTreeNode left, BinTreeNode right){
        //构造一个二叉树
        BinTreeNode temp=new BinTreeNode(left, right, item);
        return temp;
    }
//在结点类的基础上构造一个二叉树
    public static BinTreeNode makeTree(){
        BinTreeNode a,b,c,d,e,f,g,h;
        
        g=getTreeNode(new Character('G'), null, null);
        d=getTreeNode(new Character('D'), null, g);
        b=getTreeNode(new Character('B'), d, null);
        e=getTreeNode(new Character('E'), null, null);
        f=getTreeNode(new Character('F'), null, null);
        c=getTreeNode(new Character('C'), e, f);
        return getTreeNode(new Character('A'), b, c);
    }

(2) 打印一棵二叉树

 1 //打印二叉树,主要将纵向的二叉树横过来,基本的思维是先打印右子树,根节点,左子树
 2     public static void printBiTree(BinTreeNode root, int level){
 3         if (root!=null) {
 4             //根节点root的level+1层开始输出右子树,不断的递归调用
 5             printBiTree(root.getRightChild(), level+1);
 6             
 7             if (level!=0) {
 8                 for(int i=0; i<6*(level-1); i++){
 9                     System.out.print(" ");
10                 }
11                 System.out.print("---");
12             }
13             System.out.println(root.getData());         //输出结点数据元素的值
14             
15             //根节点root的level+1层开始输出左二叉树,不断的递归调用
16             printBiTree(root.getLeftChild(), level+1);
17         }
18     }

(3):查找二叉树中的某个元素

 1 //定义一个方法在二叉树中查找某个(x)元素
 2     public static BinTreeNode search(BinTreeNode t,Object x){
 3         
 4         BinTreeNode temp;
 5         if (t==null) return null;                //查询失败
 6         if (t.getData().equals(x)) return t;     //查找成功返回某个子二叉树
 7         
 8         //在左子树寻找元素
 9         if(t.getLeftChild()!=null){
10             temp=search(t.getLeftChild(), x);
11             if (temp!=null) return temp;
12         }
13         //在右子树中寻找元素
14         if(t.getRightChild()!=null){
15             temp=search(t.getRightChild(), x);
16             if (temp!=null) return temp;
17         }    
18         return null;        //查询失败的出口
19     }

(5):实现二叉树中最重要的遍历,用递归的方法实现。当然后面肯定有非递归的方法。

首先需要定义一个访问二叉树结点的方法

1 /*
2  * 定义一个类用于打印输出每个结点
3  */
4 public class Visit {
5     public void print(Object item){
6         System.out.print(item+" ");
7     }
8 }
/*
 * 定义一个用于遍历二叉树的类
 */
public class BinTraverse {
    
    //前序遍历
    public static void preOrder(BinTreeNode t, Visit v){
            //如果是非递归的方法遍历二叉树,此时这里面的if 还能用if吗?
        if (t!=null) {
            v.print(t.getData());
            preOrder(t.getLeftChild(), v);
            preOrder(t.getRightChild(), v);
        }
    }
    
    //中序遍历
    public static void inOrder(BinTreeNode t, Visit v){
        if (t!=null) {
            inOrder(t.getLeftChild(), v);
            v.print(t.getData());
            inOrder(t.getRightChild() , v);
        }
    }
    
    //后序遍历
    public static void postOrder(BinTreeNode t, Visit v){
        if (t!=null) {
            postOrder(t.getLeftChild(), v);
            postOrder(t.getRightChild(), v);
            v.print(t.getData());
        }
    }
    
    //层序遍历,层序遍历的基本原理是,每遍历一个根节点则进去左右两个孩子节点
    //逻辑类似于队列,先进先出
    public static void levelOrder(BinTreeNode t, Visit v) throws Exception{
        LinQueue lq=new LinQueue();                  //这里面需要链式队列的类型
        
        if (t==null)  return;
        BinTreeNode curr;
        lq.append(t);
        while (lq.notEmpty()) {
            curr=(BinTreeNode) lq.delete();            //从队列中删除根节点,并且将队列转化为二叉树的一个结点
            v.print(curr.getData());                //并且输出该节点的值
            //将左右结点分别插入到队列中
            if (curr.getLeftChild()!=null) 
                lq.append(curr.getLeftChild());
            if (curr.getRightChild()!=null) 
                lq.append(curr.getRightChild());
        }
    }
}

 1     /*
 2      * main函数 
 3      */
 4     public static void main(String[] args) {
 5         BinTreeNode root1;
 6         BinTreeNode temp2;
 7         
 8         Visit v=new Visit();
 9         
10         root1=makeTree();
11         System.out.println("二叉树为: ");
12         printBiTree(root1, 0);
13         System.out.println();
14         
15         
16         System.out.println("前序遍历节点序列为:");
17         BinTraverse.preOrder(root1, v);
18         System.out.println();
19         
20         System.out.println("中序遍历节点序列为:");
21         BinTraverse.inOrder(root1, v);
22         System.out.println();
23         
24         System.out.println("后序遍历节点序列为:");
25         BinTraverse.postOrder(root1, v);
26         System.out.println();
27         
28         
29         //查找某个元素
30         temp2=search(root1, new Character('F'));
31         if (temp2!=null) {
32             System.out.println("查到该节点的数据元素为: "+temp2.getData());
33         }
34         else{
35             System.out.println("查找失败!");
36         }

 **************上面说道二叉树的建立,有两种方法,下面实现第二种方便生成二叉树,在结点的基础之上建立二叉树的类。**********

(1)二叉树结点类

 1 /*
 2  * 定义一个二叉树的结点类
 3  */
 4 public class BinTreeNode {
 5     private BinTreeNode leftChild;
 6     private BinTreeNode rightChild;
 7     private Object data;
 8     
 9     public BinTreeNode(){
10         leftChild=null;
11         rightChild=null;
12     }
13     
14     public BinTreeNode(BinTreeNode left, BinTreeNode right,Object Idata){
15         leftChild=left;
16         rightChild=right;
17         data=Idata;
18     }
19 
20     public BinTreeNode getLeftChild() {
21         return leftChild;
22     }
23 
24     public BinTreeNode getRightChild() {
25         return rightChild;
26     }
27 
28     public Object getData() {
29         return data;
30     }
31 }

在二叉树结点类的基础上实现二叉树

 1 /*
 2  * 先在二叉树结点类的基础上,设计二叉树类
 3  */
 4 public class BinTree {
 5     private BinTreeNode root;                //根指针
 6     
 7     
 8     //前序遍历
 9     public void preOrder(BinTreeNode t, Visit s){
10         if (t!=null) {
11             s.print(t.getData());
12             preOrder(t.getLeftChild(), s);
13             preOrder(t.getRightChild(), s);
14         }
15     }
16     
17     //中序遍历
18     public void inOrder(BinTreeNode t, Visit s){
19         if (t!=null) {
20             inOrder(t.getLeftChild(), s);
21             s.print(t.getData());
22             inOrder(t.getRightChild(), s);
23         }
24     }
25     
26     //后序遍历
27     public void postOrder(BinTreeNode t, Visit s){
28         if (t!=null) {
29             postOrder(t.getLeftChild(), s);
30             postOrder(t.getRightChild(), s);
31             s.print(t.getData());
32         }
33     }
34     
35     //构造函数用于初始化root结点
36             public BinTree(){
37                 root= null;
38             }
39             
40             //构造函数用于处理一个二叉树
41             public BinTree( BinTree left, BinTree right,Object item){
42                 BinTreeNode leftNode;
43                 BinTreeNode rightNode;
44                 
45                 if (left==null) {
46                     leftNode=null;
47                 }else{
48                     leftNode=left.root;                //让左子树获得左子树的结点
49                 }
50                 
51                 if (right==null) {
52                     rightNode=null;
53                 }else{
54                     rightNode=right.root;
55                 }
56                 
57                 root=new BinTreeNode(leftNode, rightNode, item);
58                 
59             }    
60     
61     //前序遍历 在二叉树类遍历的基础上,调用二叉树结点遍历方法还是让二叉树结点类实现递归作用,因为最终遍历的都是书的结点
62     public void preOrder(Visit vs){
63         preOrder(root, vs);
64     }
65     
66     //中序遍历
67     public void inOrder(Visit vs){
68         inOrder(root, vs);
69     }
70     
71     //后序遍历
72     public void postOrder(Visit vs){
73         postOrder(root, vs);
74     }
75 }

 写一个测试类,包括二叉树的建立,以及二叉树的遍历。

 1 public static void main(String[] args) {
 2         
 3         //构造第二种方法的二叉树
 4         BinTree g=new BinTree(null, null, new Character('G'));
 5         BinTree d=new BinTree(null, g, new Character('D'));
 6         BinTree b=new BinTree(d, null, new Character('B'));
 7         BinTree e=new BinTree(null, null, new Character('E'));
 8         BinTree f=new BinTree(null, null, new Character('F'));
 9         BinTree c=new BinTree(e, f, new Character('C'));
10         BinTree a=new BinTree(b, c, new Character('A'));
11         
12         
13         Visit v=new Visit();
14         
15         System.out.print("前序遍历结点序列为:");
16         a.preOrder(v);
17         System.out.println();
18         
19         System.out.print("中序遍历结点序列为:");
20         a.inOrder(v);
21         System.out.println();
22         
23         System.out.print("后序遍历结点序列为:");
24         a.postOrder(v);
25         System.out.println();
26     }

大体的实现就是这样,还是感叹一句啊,在能够完全理解的情况下还是要多敲代码啊!!!!

No more talking,show me coding!!

下一节:非递归的二叉树遍历。

原文地址:https://www.cnblogs.com/xiaxj/p/6564811.html