欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

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

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

下面是代碼:

首先定義哈夫曼樹(shù)結(jié)點(diǎn)

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 + "]";
  }

}

定義一下哈夫曼樹(shù)的異常類

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

  public TreeException() {}

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

}

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

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

}

測(cè)試類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);
    }
  }

}

測(cè)試結(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]

圖形表示:

測(cè)試類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);
    }
  }

}

測(cè)試結(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]

圖形表示:

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • idea中解決maven包沖突的問(wèn)題(maven helper)

    idea中解決maven包沖突的問(wèn)題(maven helper)

    這篇文章主要介紹了idea中解決maven包沖突的問(wèn)題(maven helper),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12
  • SpringBoot中的YAML配置文件和日志詳解

    SpringBoot中的YAML配置文件和日志詳解

    這篇文章主要介紹了SpringBoot中的YAML配置文件和日志的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-12-12
  • 快速理解spring中的各種注解

    快速理解spring中的各種注解

    這篇文章主要介紹了快速理解spring中的各種注解,具有一定借鑒價(jià)值,需要的朋友可以了解下。
    2017-12-12
  • 如何區(qū)分JAVA中的equals與==

    如何區(qū)分JAVA中的equals與==

    這篇文章主要介紹了如何區(qū)分JAVA中的equals與==,文章簡(jiǎn)單易懂,實(shí)例代碼幫助大家更好的參考學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • java 實(shí)現(xiàn)文件夾的拷貝實(shí)例代碼

    java 實(shí)現(xiàn)文件夾的拷貝實(shí)例代碼

    這篇文章主要介紹了java 實(shí)現(xiàn)文件夾的拷貝實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • 6種方法初始化JAVA中的list集合

    6種方法初始化JAVA中的list集合

    這篇文章主要介紹了6種方法初始化JAVA中的list集合,文中講解非常詳細(xì),代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • java面向?qū)ο笾藱C(jī)猜拳小游戲

    java面向?qū)ο笾藱C(jī)猜拳小游戲

    這篇文章主要為大家詳細(xì)介紹了java面向?qū)ο笾藱C(jī)猜拳小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • Java中new關(guān)鍵字和newInstance方法的區(qū)別分享

    Java中new關(guān)鍵字和newInstance方法的區(qū)別分享

    在初始化一個(gè)類,生成一個(gè)實(shí)例的時(shí)候,newInstance()方法和new關(guān)鍵字除了一個(gè)是方法一個(gè)是關(guān)鍵字外,最主要的區(qū)別是創(chuàng)建對(duì)象的方式不同
    2013-07-07
  • SpringMVC ajax請(qǐng)求的處理方法介紹

    SpringMVC ajax請(qǐng)求的處理方法介紹

    Ajax即異步的 JavaScript和XML,是一種無(wú)需重新加載整個(gè)網(wǎng)頁(yè)的情況下,能夠更新部分模塊的網(wǎng)頁(yè)技術(shù),下面這篇文章主要給大家介紹了關(guān)于SpringMVC Ajax請(qǐng)求的處理,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-11-11
  • idea項(xiàng)目中target文件提示拒絕訪問(wèn)的解決

    idea項(xiàng)目中target文件提示拒絕訪問(wèn)的解決

    這篇文章主要介紹了idea項(xiàng)目中target文件提示拒絕訪問(wèn)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11

最新評(píng)論