最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 最優(yōu)二叉樹的哈夫曼算法的簡單實現(xiàn)

 更新時間:2019年10月02日 11:11:11   作者:進階的JFarmer  
這篇文章主要介紹了Java 最優(yōu)二叉樹的哈夫曼算法的簡單實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

最優(yōu)二叉樹也稱哈夫曼樹,講的直白點就是每個結(jié)點都帶權(quán)值,我們讓大的值離根近、小的值離根遠,實現(xiàn)整體權(quán)值(帶權(quán)路徑長度)最小化。

哈夫曼算法的思想我認為就是上面講的,而它的算法實現(xiàn)思路是這樣的:
從根結(jié)點中抽出權(quán)值最小的兩個(涉及排序,但是我這個實現(xiàn)代碼沒做嚴格的排序,只有比較)合并出新的根結(jié)點重新加入排序(被抽出來的兩個自然是變成非根結(jié)點了?。?,就這樣循環(huán)下去,直到合并完成,我們得到一顆最優(yōu)二叉樹——哈夫曼樹。

說明:
(1)哈夫曼樹有n個葉子結(jié)點,則我們可以推出其有n-1個分支結(jié)點。因此我在定義名為huffmanTree的HuffmanNode類型數(shù)組時定義長度為2*n-1。
(2)這里排序相關(guān)沒有做得很好,只是為了實現(xiàn)而實現(xiàn),以后慢慢完善。
(3)理論上講哈夫曼樹應該是不僅僅局限于數(shù)值,能compare就行,但這里只用int表示。

下面是代碼:

首先定義哈夫曼樹結(jié)點

public class HuffmanNode {
  
  private int weight = -1;
  
  private int parent = -1;
  
  private int left = -1;
  
  private int right = -1;

  public HuffmanNode(int weight) {
    super();
    this.weight = weight;
  }

  public HuffmanNode(int weight, int left, int right) {
    super();
    this.weight = weight;
    this.left = left;
    this.right = right;
  }

  public int getWeight() {
    return weight;
  }

  public void setWeight(int weight) {
    this.weight = weight;
  }

  public int getParent() {
    return parent;
  }

  public void setParent(int parent) {
    this.parent = parent;
  }

  public int getLeft() {
    return left;
  }

  public void setLeft(int left) {
    this.left = left;
  }

  public int getRight() {
    return right;
  }

  public void setRight(int right) {
    this.right = right;
  }

  @Override
  public String toString() {
    return "HuffmanNode [weight=" + weight + ", parent=" + parent + ","
        + " left=" + left + ", right=" + right + "]";
  }

}

定義一下哈夫曼樹的異常類

public class TreeException extends RuntimeException {
  
  private static final long serialVersionUID = 1L;

  public TreeException() {}

  public TreeException(String message) {
    super(message);
  }

}

編碼實現(xiàn)(做的處理不是那么高效)

public class HuffmanTree {
  
  protected HuffmanNode[] huffmanTree;
  
  public HuffmanTree(int[] leafs) {
    //異常條件判斷
    if (leafs.length <= 1) {
      throw new TreeException("葉子結(jié)點個數(shù)小于2,無法構(gòu)建哈夫曼樹");
    }
    //初始化儲存空間
    huffmanTree = new HuffmanNode[leafs.length*2-1];
    //構(gòu)造n棵只含根結(jié)點的二叉樹
    for (int i = 0; i < leafs.length; i++) {
      HuffmanNode node = new HuffmanNode(leafs[i]);
      huffmanTree[i] = node;
    }
    //構(gòu)造哈夫曼樹的選取與合并
    for (int i = leafs.length; i < huffmanTree.length; i++) {
      //獲取權(quán)值最小的結(jié)點下標
      int miniNum_1 = selectMiniNum1();
      //獲取權(quán)值次小的結(jié)點下標
      int miniNum_2 = selectMiniNum2();
      if (miniNum_1 == -1 || miniNum_2 == -1) {
        return;
      }
      //兩個權(quán)值最小的結(jié)點合并為新節(jié)點
      HuffmanNode node = new HuffmanNode(huffmanTree[miniNum_1].getWeight() + 
          huffmanTree[miniNum_2].getWeight(), miniNum_1, miniNum_2);
      huffmanTree[i] = node;
      huffmanTree[miniNum_1].setParent(i);
      huffmanTree[miniNum_2].setParent(i);
    }
  }
  
  /**
   * 獲取權(quán)值最小的結(jié)點下標
   * @return
   */
  private int selectMiniNum1() {
    //最小值
    int min = -1;
    //最小值下標
    int index = -1;
    //是否完成最小值初始化
    boolean flag = false;
    //遍歷一遍
    for (int i = 0; i < huffmanTree.length; i++) {
      //排空、只看根結(jié)點,否則跳過
      if (huffmanTree[i] == null || huffmanTree[i].getParent() != -1) {
        continue;
      } else if (!flag) {   //沒初始化先初始化然后跳過
        //初始化
        min = huffmanTree[i].getWeight();
        index = i;
        //以后不再初始化min
        flag = true;
        //跳過本次循環(huán)
        continue;
      }
      int tempWeight = huffmanTree[i].getWeight();
      //低效比較
      if (tempWeight < min) {
        min = tempWeight;
        index = i;
      }
    }
    return index;
  }
  
  /**
   * 獲取權(quán)值次小的結(jié)點下標
   * @return
   */
  private int selectMiniNum2() {
    //次小值
    int min = -1;
    //是否完成次小值初始化
    boolean flag = false;
    //最小值下標(調(diào)用上面的方法)
    int index = selectMiniNum1();
    //最小值都不存在,則次小值也不存在
    if (index == -1) {
      return -1;
    }
    //次小值下標
    int index2 = -1;
    //遍歷一遍
    for (int i = 0; i < huffmanTree.length; i++) {
      //最小值不要、排空、只看根結(jié)點,否則跳過
      if (index == i || huffmanTree[i] == null || huffmanTree[i].getParent() != -1) {
        continue;
      } else if (!flag) {   //沒初始化先初始化然后跳過
        //初始化
        min = huffmanTree[i].getWeight();
        index2 = i;
        //以后不再初始化min
        flag = true;
        //跳過本次循環(huán)
        continue;
      }
      int tempWeight = huffmanTree[i].getWeight();
      //低效比較
      if (tempWeight < min) {
        min = tempWeight;
        index2 = i;
      }
    }
    return index2;
  }

}

測試類1

public class HuffmanTreeTester {

  public static void main(String[] args) {
    int[] leafs = {1, 3, 5, 6, 2, 22, 77, 4, 9};
    HuffmanTree tree = new HuffmanTree(leafs);
    HuffmanNode[] nodeList = tree.huffmanTree;
    for (HuffmanNode node : nodeList) {
      System.out.println(node);
    }
  }

}

測試結(jié)果1

HuffmanNode [weight=1, parent=9, left=-1, right=-1]
HuffmanNode [weight=3, parent=10, left=-1, right=-1]
HuffmanNode [weight=5, parent=11, left=-1, right=-1]
HuffmanNode [weight=6, parent=12, left=-1, right=-1]
HuffmanNode [weight=2, parent=9, left=-1, right=-1]
HuffmanNode [weight=22, parent=15, left=-1, right=-1]
HuffmanNode [weight=77, parent=16, left=-1, right=-1]
HuffmanNode [weight=4, parent=11, left=-1, right=-1]
HuffmanNode [weight=9, parent=13, left=-1, right=-1]
HuffmanNode [weight=3, parent=10, left=0, right=4]
HuffmanNode [weight=6, parent=12, left=1, right=9]
HuffmanNode [weight=9, parent=13, left=7, right=2]
HuffmanNode [weight=12, parent=14, left=3, right=10]
HuffmanNode [weight=18, parent=14, left=8, right=11]
HuffmanNode [weight=30, parent=15, left=12, right=13]
HuffmanNode [weight=52, parent=16, left=5, right=14]
HuffmanNode [weight=129, parent=-1, left=15, right=6]

圖形表示:

測試類2

public class HuffmanTreeTester {

  public static void main(String[] args) {
    int[] leafs = {2, 4, 5, 3};
    HuffmanTree tree = new HuffmanTree(leafs);
    HuffmanNode[] nodeList = tree.huffmanTree;
    for (HuffmanNode node : nodeList) {
      System.out.println(node);
    }
  }

}

測試結(jié)果2

HuffmanNode [weight=2, parent=4, left=-1, right=-1]
HuffmanNode [weight=4, parent=5, left=-1, right=-1]
HuffmanNode [weight=5, parent=5, left=-1, right=-1]
HuffmanNode [weight=3, parent=4, left=-1, right=-1]
HuffmanNode [weight=5, parent=6, left=0, right=3]
HuffmanNode [weight=9, parent=6, left=1, right=2]
HuffmanNode [weight=14, parent=-1, left=4, right=5]

圖形表示:

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Mybatis?Lombok使用方法與復雜查詢介紹

    Mybatis?Lombok使用方法與復雜查詢介紹

    Lombok是一種Java實用工具,可用來幫助開發(fā)人員消除Java的冗長,尤其是對于簡單的Java對象(POJO),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2022-10-10
  • Java中stream是什么及如何使用

    Java中stream是什么及如何使用

    在Java中,Stream(流)是一種用于操作集合(Collection)、數(shù)組等數(shù)據(jù)源的API,Stream的主要作用是進行數(shù)據(jù)的轉(zhuǎn)換、篩選、聚合等操作,可以極大地簡化對數(shù)據(jù)的處理,本文給大家介紹Java中stream是什么?有什么作用?如何使用?感興趣的朋友一起看看吧
    2023-10-10
  • Java設計模式之動態(tài)代理

    Java設計模式之動態(tài)代理

    今天小編就為大家分享一篇關(guān)于Java設計模式之動態(tài)代理,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • Java工程師面試題一面二面整理

    Java工程師面試題一面二面整理

    在本篇文章里小編給大家整理的是關(guān)于Java 工程師面試題的相關(guān)知識點,有需要的可以參考下。
    2019-08-08
  • SpringBoot詳細講解如何創(chuàng)建及刷新Spring容器bean

    SpringBoot詳細講解如何創(chuàng)建及刷新Spring容器bean

    前面看spring源碼時可以發(fā)現(xiàn)refresh()方法十分重要。在這個方法中會加載beanDefinition,同時創(chuàng)建bean對象。那么在springboot中有沒有使用這個refresh()方法呢
    2022-06-06
  • 在Mac下IDEA安裝并使用protobuf方式(Java)

    在Mac下IDEA安裝并使用protobuf方式(Java)

    這篇文章主要介紹了在Mac下IDEA安裝并使用protobuf方式(Java),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Java多線程間的5種通信方式小結(jié)

    Java多線程間的5種通信方式小結(jié)

    有兩個線程,A 線程向一個集合里面依次添加元素“abc”字符串,一共添加十次,當添加到第五次的時候,希望 B 線程能夠收到 A 線程的通知,然后 B 線程執(zhí)行相關(guān)的業(yè)務操作,本文介紹的5種通信方式都是基本這兩種模型來實現(xiàn)的,需要的朋友可以參考下
    2023-10-10
  • Spring Bean 依賴注入常見錯誤問題

    Spring Bean 依賴注入常見錯誤問題

    這篇文章主要介紹了Spring Bean 依賴注入常見錯誤問題,文中提到value的工作大體分為三個核心步驟,具體內(nèi)容詳情跟隨小編一起看看吧
    2021-09-09
  • Spring Boot之FilterRegistrationBean-自定義Filter詳解

    Spring Boot之FilterRegistrationBean-自定義Filter詳解

    這篇文章主要介紹了Spring Boot之FilterRegistrationBean-自定義Filter詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java設計模式之單件模式深入講解

    Java設計模式之單件模式深入講解

    有人說單件模式是最簡單的模式,因為它只有一個類,但其實它還有一些值得注意的地方,就如:出現(xiàn)并發(fā)性時,單件可能已經(jīng)不是單件了
    2021-11-11

最新評論

香河县| 武定县| 扎赉特旗| 遵义市| 南昌县| 兴海县| 正定县| 徐水县| 三原县| 三门县| 渝北区| 苏尼特右旗| 察雅县| 贞丰县| 浪卡子县| 陇西县| 定安县| 荥阳市| 花莲县| 迁西县| 平顶山市| 璧山县| 汝南县| 贺州市| 东乡| 丰台区| 三河市| 咸阳市| 凤城市| 潞城市| 罗江县| 密云县| 马山县| 驻马店市| 依兰县| 聂荣县| 景德镇市| 神木县| 内丘县| 伽师县| 托里县|