• java-实现 哈夫曼树 二叉查找树


    二叉树的应用

    1,哈夫曼树和哈夫曼编码

     //转载至:https://blog.csdn.net/jdhanhua/article/details/6621026

    1.1首先是Node类,因为每次取出两个最小值都行从新排序,将Node实现

    Comparable接口用于排序

     1 public class Node implements Comparable<Node>{
     2     public int data=Integer.MAX_VALUE;
     3     public Node lchild=null;
     4     public Node rchild=null;
     5 
     6     public Node(){}
     7     public Node(int data){
     8         this.data=data;
     9     }
    10 
    11     @Override
    12     public int compareTo(Node o) {
    13         if(o.data>this.data)
    14             return 1;
    15         if(o.data<this.data)
    16             return -1;
    17         return 0;
    18     }
    19 }
    View Code

    1.2,hafuffmanTree类

      1 import java.util.*;
      2 
      3 /**
      4  *
      5  * 建树,
      6  * 输出哈夫曼编码
      7  */
      8 
      9 
     10 public class HaffmanTree {
     11     private Node root=new Node();
     12 
     13     /**
     14      * 建树-①根据已排序的升序频率数组建树,每次取出前两个创建树,根节点为前两个和
     15      * ②将根节点插入数组,重新排序,重复①,直至结束
     16      * https://blog.csdn.net/jdhanhua/article/details/6621026
     17      */
     18     public Node createHaffmanTree(List<Node> array){
     19         while(array.size()>1){
     20             Collections.sort(array);
     21             Node left=array.get(array.size()-1);
     22             Node right=array.get(array.size()-2);
     23             Node newNode=new Node(left.data+right.data);
     24             newNode.lchild=left;
     25             newNode.rchild=right;
     26             array.remove(left);
     27             array.remove(right);
     28             array.add(newNode);
     29             //System.out.println("data: "+newNode.data);
     30         }
     31         return array.get(0);
     32     }
     33 
     34     /**
     35      * 打印编码
     36        https://www.it610.com/article/1296876477320601600.htm
     37      遍历的时候加一个编码栈
     38      * 遍历的时候,进入左子树,0入栈,右子树,1入栈,
     39      * 遍历到叶子节点-输出,打印栈,
     40      *返回时栈顶退栈
     41      */
     42     public void HaffmanCode(Node root,Stack<Integer>stack){
     43         if(root==null)
     44             return;
     45         if(root.rchild==null&&root.rchild==null)//叶子节点
     46             System.out.println(root.data+" "+stack);
     47         stack.push(0);
     48         HaffmanCode(root.lchild,stack);
     49         stack.pop();
     50 
     51         stack.push(1);
     52         HaffmanCode(root.rchild,stack);
     53         stack.pop();
     54     }
     55     //打印树-复制上一篇
     56     //H为频率数组个数
     57     public void printTree(Node root,int H){
     58         int h=H;
     59         //System.out.println("树高:"+H);
     60         if(H==0)
     61             System.out.println("树空,无打印");
     62         else{
     63             System.out.println("打印树:");
     64             Queue<Node> queue=new LinkedList<>();
     65             queue.add(root);
     66             int height=1;
     67             //记录每层孩子个数
     68             int len=1;
     69             while(h>0){
     70                 int length=0;
     71                 String space="";
     72                 for(int i=0;i<(((Math.pow(2,H)+1)*3)/(Math.pow(2,height)+1));i++)
     73                     space+=" ";
     74                 for(int i=0;i<len;i++){
     75                     Node curroot=queue.poll();
     76                     if(curroot.data==Integer.MAX_VALUE){
     77                         System.out.print(space);
     78                     }else
     79                         System.out.print(space+curroot.data);
     80 
     81                     if(curroot.lchild!=null){
     82                         queue.add(curroot.lchild);
     83                     }
     84                     else
     85                         queue.add(new Node());
     86                     length++;
     87                     if(curroot.rchild!=null){
     88                         queue.add(curroot.rchild);
     89                     }
     90                     else
     91                         queue.add(new Node());
     92                     length++;
     93                 }
     94                 System.out.println();
     95                 System.out.println();
     96                 len=length;
     97                 height++;
     98                 h--;
     99             }
    100             System.out.println();
    101         }
    102     }
    103 
    104     //1,2,5,8,7,9
    105     public static void main(String args[]) {
    106         List<Node> l=new ArrayList<Node>();
    107         l.add(new Node(1));
    108         l.add(new Node(2));
    109         l.add(new Node(5));
    110         l.add(new Node(8));
    111         l.add(new Node(7));
    112         l.add(new Node(9));
    113         int H=l.size();
    114         System.out.println("l  "+l.size());
    115 
    116         HaffmanTree h=new HaffmanTree();
    117         h.root=h.createHaffmanTree(l);
    118 
    119         h.printTree(h.root,H);
    120         Stack<Integer> stack=new Stack<>();
    121         h.HaffmanCode(h.root,stack);
    122         
    123     }
    124 
    125 
    126 }
    View Code

    2,二叉查找树

     2.1,先实现二叉查找树的排序功能

             如果在建树的时候安照,若插入节点值小于根节点值,往根节点左子树继续,大于根节点值

          往右子树继续,如无左/右子树则插入。建树完成后,形成的树的中序遍历结构就是升序的。

    如按 {4,2,3,8,7,9,1}  顺序插入建树如图,中序遍历为:1234789

    Node类同hafuffman 树,就不写了

    sortBiTree

      1 /**
      2  * 二叉搜索树的排序功能
      3  * 给你个待排序数组
      4  * 建树,中序遍历树
      5  *
      6  * 缺点:
      7  * 当待排序的序列为顺序或逆序时,很不稳定,需要平衡二叉树或红黑树那种
      8  * 后面再学
      9  */
     10 import java.util.LinkedList;
     11 import java.util.Queue;
     12 public class SortBitree {
     13     private Node root=null;
     14 
     15 
     16     /**
     17      * 建树
     18      * 空-插入根节点,比根节点小,进入左子树,
     19      * 比根节点大,进入右子树
     20      */
     21     public void inseart(Node root,int data){
     22         //System.out.println(root.data);
     23         if(root==null)
     24             this.root=new Node(data);
     25         else{
     26             //元素不能重复,
     27             if(data<root.data){
     28                 if(root.lchild==null){
     29                     root.lchild=new Node(data);
     30                 }
     31                 else{
     32                     inseart(root.lchild,data);
     33                 }
     34             }
     35             else{
     36                 if(root.rchild==null){
     37                     root.rchild=new Node(data);
     38                 }else
     39                     inseart(root.rchild,data);
     40             }
     41         }
     42     }
     43     //递归求树高-用于打印
     44     //递归
     45     public int treeHeightRec(Node root){
     46         if(root==null||root.data==Integer.MAX_VALUE)
     47             return 0;
     48         else{
     49             int a =treeHeightRec(root.lchild);
     50             int b = treeHeightRec(root.rchild);
     51             return (a>b)?(a+1):(b+1);
     52         }
     53     }
     54     //打印树--233,复制前一篇的方法,如果树层数很深时,打印的比较别扭
     55     public void printTree(Node root){
     56         int H=treeHeightRec(root);
     57         int h=H;
     58         //System.out.println("树高:"+H);
     59         if(H==0)
     60             System.out.println("树空,无打印");
     61         else{
     62             System.out.println("打印树:");
     63             Queue<Node> queue=new LinkedList<>();
     64             queue.add(root);
     65             int height=1;
     66             //记录每层孩子个数
     67             int len=1;
     68             while(h>0){
     69                 int length=0;
     70                 String space="";
     71                 for(int i=0;i<(((Math.pow(2,H)+1)*3)/(Math.pow(2,height)+1));i++)
     72                     space+=" ";
     73                 for(int i=0;i<len;i++){
     74                     Node curroot=queue.poll();
     75                     if(curroot.data==Integer.MAX_VALUE){
     76                         System.out.print(space);
     77                     }else
     78                         System.out.print(space+curroot.data);
     79 
     80                     if(curroot.lchild!=null){
     81                         queue.add(curroot.lchild);
     82                     }
     83                     else
     84                         queue.add(new Node());
     85                     length++;
     86                     if(curroot.rchild!=null){
     87                         queue.add(curroot.rchild);
     88                     }
     89                     else
     90                         queue.add(new Node());
     91                     length++;
     92                 }
     93                 System.out.println();
     94                 System.out.println();
     95                 len=length;
     96                 height++;
     97                 h--;
     98             }
     99             System.out.println();
    100         }
    101     }
    102     //中序遍历
    103     public void inOrder(Node root){
    104         if(root==null)
    105             return;
    106         inOrder(root.lchild);
    107         System.out.print(root.data+" ");
    108         inOrder(root.rchild);
    109     }
    110     
    111     public static void main(String args[]) {
    112         SortBitree t=new SortBitree();
    113         SortBitree t1=new SortBitree();
    114         SortBitree t2=new SortBitree();
    115         int[] array={4,2,3,8,7,9,1};
    116         int[] array1={1,2,3,4,5,6,7};
    117         int[] array2={7,6,5,4,3,2,1};
    118 
    119         for(int i=0;i<array.length;i++){
    120             t.inseart(t.root,array[i]);
    121         }
    122         System.out.print("排序后的序列: ");t.inOrder(t.root);
    123         System.out.println();
    124         t.printTree(t.root);
    125 
    126         for(int i=0;i<array.length;i++){
    127             t1.inseart(t1.root,array1[i]);
    128         }
    129         System.out.print("排序后的序列: ");t1.inOrder(t1.root);
    130         System.out.println();
    131         t1.printTree(t1.root);
    132 
    133         for(int i=0;i<array.length;i++){
    134             t2.inseart(t.root,array2[i]);
    135         }
    136         System.out.print("排序后的序列: ");t2.inOrder(t2.root);
    137         System.out.println();
    138         t2.printTree(t2.root);
    139 
    140     }
    141     
    142     
    143     
    144 }
    View Code

    2.2,完整二叉查找树

           排序功能涉及了二叉查找树的插入功能,还有查找,删除功能

    查找功能比较简单,二叉遍历一遍,主要是删除功能,比较复杂

    /**删除
    * ①删除最小/大值,最小/大值-最左/右节点
    * -空树
    * -只有一个根节点
    * -根节点无左/右子树(删除根节点)
    * -有左/右子树且非空
    *
    * ②删除一个节点,-树空
    * -是否在树中
    * -无左右节点,直接删
    * -有左节点(只有左子树),删除左子树的最大节点-返回最大节点,
    * 将返回的节点代替被删节点
    * -只要有右节点,删除右子树的最小值,将返回的节点代替被删节点
    */

    完整代码
      1 //https://www.cnblogs.com/songdechiu/p/6821168.html
      2 //转载一个老哥,太猛了-(key,value)
      3 //这篇也不错---(value)
      4 //https://zhuanlan.zhihu.com/p/84517029
      5 
      6 import java.util.LinkedList;
      7 import java.util.Queue;
      8 
      9 /**二叉查找树-完成的
     10  * 建树-就是不停插入(二叉排序树简单铺垫了,直接复制过来)
     11  * 插入
     12  *
     13  * 查找
     14  *
     15  * 删除
     16  */
     17 
     18 public class SearchBiTree {
     19     private Node root=null;
     20 
     21 
     22     /**
     23      * 打印等辅助函数
     24      */
     25     //递归求树高-用于打印树
     26     //递归
     27     public int treeHeightRec(Node root){
     28         if(root==null||root.data==Integer.MAX_VALUE)
     29             return 0;
     30         else{
     31             int a =treeHeightRec(root.lchild);
     32             int b = treeHeightRec(root.rchild);
     33             return (a>b)?(a+1):(b+1);
     34         }
     35     }
     36     //打印树--233,复制前一篇的方法,如果树层数很深时,打印的比较别扭
     37     public void printTree(Node root){
     38         int H=treeHeightRec(root);
     39         int h=H;
     40         //System.out.println("树高:"+H);
     41         if(H==0)
     42             System.out.println("树空,无打印");
     43         else{
     44             System.out.println("打印树:");
     45             Queue<Node> queue=new LinkedList<>();
     46             queue.add(root);
     47             int height=1;
     48             //记录每层孩子个数
     49             int len=1;
     50             while(h>0){
     51                 int length=0;
     52                 String space="";
     53                 for(int i=0;i<(((Math.pow(2,H)+1)*3)/(Math.pow(2,height)+1));i++)
     54                     space+=" ";
     55                 for(int i=0;i<len;i++){
     56                     Node curroot=queue.poll();
     57                     if(curroot.data==Integer.MAX_VALUE){
     58                         System.out.print(space);
     59                     }else
     60                         System.out.print(space+curroot.data);
     61 
     62                     if(curroot.lchild!=null){
     63                         queue.add(curroot.lchild);
     64                     }
     65                     else
     66                         queue.add(new Node());
     67                     length++;
     68                     if(curroot.rchild!=null){
     69                         queue.add(curroot.rchild);
     70                     }
     71                     else
     72                         queue.add(new Node());
     73                     length++;
     74                 }
     75                 System.out.println();
     76                 System.out.println();
     77                 len=length;
     78                 height++;
     79                 h--;
     80             }
     81             System.out.println();
     82         }
     83     }
     84     //中序遍历
     85     public void inOrder(Node root){
     86         if(root==null)
     87             return;
     88         inOrder(root.lchild);
     89         System.out.print(root.data+" ");
     90         inOrder(root.rchild);
     91     }
     92 
     93 
     94     /**
     95      * 以下为新加内容
     96      */
     97     //查找--是否存在
     98     public boolean isExit(Node root,int data){
     99         if(root==null)//树空
    100             return false;
    101         if(root.data==data)
    102             return true;
    103         else if(data<root.data){
    104             if(root.lchild==null)
    105                 return false;
    106             else
    107                 return isExit(root.lchild,data);
    108         }else{
    109             if(root.rchild==null)
    110                 return false;
    111             else
    112                 return isExit(root.rchild,data);
    113         }
    114     }
    115     //插入-先搜索,不存在则插入,
    116     public void inseart(Node root,int data){
    117         if(!isExit(root,data))
    118             //System.out.println(root.data);
    119             if(root==null)
    120                 this.root=new Node(data);
    121             else{
    122                 //元素不能重复,
    123                 if(data<root.data){
    124                     if(root.lchild==null){
    125                         root.lchild=new Node(data);
    126                     }
    127                     else{
    128                         inseart(root.lchild,data);
    129                     }
    130                 }
    131                 else{
    132                     if(root.rchild==null){
    133                         root.rchild=new Node(data);
    134                     }else
    135                         inseart(root.rchild,data);
    136                 }
    137             }
    138         else
    139             System.out.println(data+"已在排序树中");
    140     }
    141 
    142     /**删除
    143      * ①删除最小/大值,最小/大值-最左/右节点
    144      *                -空树
    145      *                -只有一个根节点
    146      *                -根节点无左/右子树(删除根节点)
    147      *                -有左/右子树且非空
    148      *
    149      * ②删除一个节点,-树空
    150      *                -是否在树中
    151      *                -无左右节点,直接删
    152      *                -有左节点(只有左子树),删除左子树的最大节点-返回最大节点,
    153      *                   将返回的节点代替被删节点
    154      *                -只要有右节点,删除右子树的最小值,将返回的节点代替被删节点
    155      */
    156     //删除最小值
    157     public Node deleteMin(Node root){
    158         //空树
    159         if(root==null){
    160             System.out.println("树空,无最小值");
    161             return null;
    162         }
    163         //只有一个根节点
    164         else if(root.lchild==null&&root.rchild==null){
    165             this.root=null;
    166             return root;
    167         }
    168         //根节点无左子树(删除根节点)
    169         else if(root.lchild==null){
    170             Node n=new Node(root.data);
    171             root.data=root.rchild.data;
    172             root.lchild=root.rchild.lchild;
    173             root.rchild=root.rchild.rchild;
    174             return n;
    175         }
    176         //有左子树且非空
    177         Node preNode=new Node();
    178         while(root.lchild!=null){
    179             preNode=root;
    180             root=root.lchild;
    181         }
    182         preNode.lchild=root.rchild;
    183         return root;
    184     }
    185     //删除最大值
    186     public Node deleteMax(Node root){
    187         //空树
    188         if(root==null){
    189             System.out.println("树空,无最大值");
    190             return null;
    191         }
    192         //只有一个根节点
    193         else if(root.lchild==null&&root.rchild==null){
    194             this.root=null;
    195             return root;
    196         }
    197         //根节点无右子树(删除根节点)
    198         else if(root.rchild==null){
    199             Node n=new Node(root.data);
    200             root.data=root.lchild.data;
    201             root.lchild=root.lchild.lchild;
    202             root.rchild=root.lchild.rchild;
    203             return n;
    204         }
    205         //有右子树且非空
    206         Node preNode=new Node();
    207         while(root.rchild!=null){
    208             preNode=root;
    209             root=root.rchild;
    210         }
    211         preNode.rchild=root.lchild;
    212         return root;
    213     }
    214     //删除一个值
    215     public void delete(Node root,int data){
    216         //在树中(树非空)
    217         if(!isExit(root,data)){
    218             System.out.println("值不在树中");
    219         }
    220         //只有一个节点-即删除根节点
    221         if(root.lchild==null&&root.rchild==null){
    222             this.root=null;
    223         }
    224         //先遍历到节点,在删除-将替换节点的值赋给该节点,
    225         //记录被删节点何其前驱节点-非递归遍历法
    226         else{
    227             Node preNode=root;
    228             String lORr="";//记录前驱节点的哪个孩子时待删节点
    229             while(root.data!=data){
    230                 if(data<root.data){
    231                     preNode=root;
    232                     lORr="l";
    233                     root=root.lchild;
    234                 }
    235                 else if(data>root.data){
    236                     preNode=root;
    237                     lORr="r";
    238                     root=root.rchild;
    239                 }
    240             }
    241             //此时root即待删除节点;
    242             //该节点无子节点
    243             if(root.lchild==null&&root.rchild==null){
    244                 if(lORr=="l")
    245                     preNode.lchild=null;
    246                 else
    247                     preNode.rchild=null;
    248             }
    249             //只有左子节点
    250             else if(root.lchild!=null&&root.rchild==null){
    251                 //如果左子节点是叶子节点--因为根节点表示问题,左子树只有根节点,数据是写入特殊值Integer.MAX_VALUE
    252                 //而不是删掉=null
    253                 if(root.lchild.lchild==null&&root.lchild.rchild==null){
    254                     if(lORr=="l")
    255                         preNode.lchild=root.lchild;
    256                     else
    257                         preNode.rchild=root.lchild;
    258                 }else{
    259                     Node replaceNode=deleteMax(root.lchild);
    260                     root.data=replaceNode.data;
    261                 }
    262             }
    263             //有右子节点
    264             else if(root.rchild!=null){
    265                 if(root.rchild.lchild==null&&root.rchild.rchild==null){
    266                     if(lORr=="l"){
    267                         preNode.lchild=root.rchild;
    268                         root.rchild.lchild=root.lchild;//接替root的左子树;
    269                     }
    270                     else{
    271                         preNode.rchild=root.rchild;
    272                         root.rchild.lchild=root.lchild;
    273                     }
    274                 }else{
    275                     Node replaceNode=deleteMin(root.rchild);
    276                     root.data=replaceNode.data;
    277                 }
    278             }
    279 
    280 
    281         }
    282     }
    283     public static void main(String args[]) {
    284         SearchBiTree t=new SearchBiTree();
    285         int[] array={8,4,6,16,14,18,2};
    286 
    287         for(int i=0;i<array.length;i++){
    288             t.inseart(t.root,array[i]);
    289         }
    290         System.out.print("排序后的序列: ");t.inOrder(t.root);
    291         System.out.println();
    292         t.printTree(t.root);
    293 
    294         t.inseart(t.root,12);
    295         t.inseart(t.root,5);
    296         t.printTree(t.root);
    297         t.inseart(t.root,16);
    298         t.inseart(t.root,13);
    299         t.printTree(t.root);
    300         t.delete(t.root,14);
    301         t.printTree(t.root);
    302 
    303 
    304         System.out.println(t.deleteMax(t.root).data);
    305         t.printTree(t.root);
    306         t.deleteMin(t.root);
    307         t.printTree(t.root);
    308 
    309         /**
    310          * 删除
    311          */
    312 
    313         SearchBiTree t2=new SearchBiTree();
    314         t2.printTree(t2.root);
    315         t2.inseart(t2.root,2);
    316         t2.printTree(t2.root);
    317         t2.deleteMin(t2.root);
    318         t2.printTree(t2.root);
    319         t2.inseart(t2.root,11);
    320         t2.inseart(t2.root,10);
    321         t2.inseart(t2.root,9);
    322         t2.inseart(t2.root,8);
    323         t2.printTree(t2.root);
    324 
    325         System.out.println(t2.deleteMax(t2.root).data);
    326         t2.printTree(t2.root);
    327 
    328 
    329 
    330 
    331     }
    332 }
    View Code
  • 相关阅读:
    Android ListView常用用法
    android ListView详解
    /使用匿名内部类来复写Handler当中的handlerMessage()方法
    android Handler的使用(一)
    Android之Handler用法总结
    动态设置android:drawableLeft|Right|Top|Bottom
    Android Drawable Resource学习(十)、ScaleDrawable
    Android开发——关于onCreate的解读
    onCreate()方法中的参数Bundle savedInstanceState 的意义用法
    Android之drawable state各个属性详解
  • 原文地址:https://www.cnblogs.com/wangpan8721/p/13699627.html
Copyright © 2020-2023  润新知