• 数据结构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!!

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

  • 相关阅读:
    Unraid 8 虚拟机 KVM(Ubuntu Server、Windows 10)
    Unraid 9 优化 IPv6 访问(LANraragi 示例)
    1451. 重新排列句子中的单词
    144. 二叉树的前序遍历
    模拟键盘输入 keybd_event()
    Hive元数据信息对应MySQL数据库表
    书单
    Manjaro Gnome Hidpi 缩放问题
    Manjaro Linux 魔兽世界 使用黑盒工坊安装插件
    nginx系列【设置开机自启动】
  • 原文地址:https://www.cnblogs.com/xiaxj/p/6564811.html
Copyright © 2020-2023  润新知