數據結構與算法-樹-哈夫曼樹

數據結構與算法-樹-哈夫曼樹

概述
給定n個權值作爲n個葉子結點,構造一棵二叉樹,若帶權路徑長度達到最小,稱這樣的二叉樹爲最優二叉樹,也稱爲哈夫曼樹(Huffman Tree)。哈夫曼樹是帶權路徑長度最短的樹,權值較大的結點離根較近。
特性

  • 對於同一組權值,所能得到的赫夫曼樹不一定是唯一的。
  • 赫夫曼樹的左右子樹可以互換,因爲這並不影響樹的帶權路徑長度。
  • 帶權值的節點都是葉子節點,不帶權值的節點都是某棵子二叉樹的根節點。
  • 權值越大的節點越靠近赫夫曼樹的根節點,權值越小的節點越遠離赫夫曼樹的根節點。
  • 赫夫曼樹中只有葉子節點和度爲2的節點,沒有度爲1的節點。一棵有n個葉子節點的赫夫曼樹共有2n-1個節點。

Huffman Tree的構建
赫夫曼樹的構建步驟如下:

  1. 將給定的n個權值看做n棵只有根節點(無左右孩子)的二叉樹,組成一個集合HT,每棵樹的權值爲該節點的權值。
  2. 從集合HT中選出2棵權值最小的二叉樹,組成一棵新的二叉樹,其權值爲這2棵二叉樹的權值之和。
  3. 將步驟2中選出的2棵二叉樹從集合HT中刪去,同時將步驟2中新得到的二叉樹加入到集合HT中。
  4. 重複步驟2和步驟3,直到集合HT中只含一棵樹,這棵樹便是赫夫曼樹。

創建
圖解
https://mp.weixin.qq.com/s/nx0OovSwYTeF8ebmzi_-VA

實現代碼

class TreeNode{
  public int val;
  public TreeNode left;
  public TreeNode right;
  
  public TreeNode(int val) {
   this.val=val;
  }
 }
 protected TreeNode root;
 /**
 *vals 是升序序列
 */
public void create(List<Integer> vals) {
  Queue<Integer> q1 = new LinkedList<>(vals);
  Queue<TreeNode> q2 = new LinkedList<>();
  
  TreeNode n1 = null;
  while(!q1.isEmpty()||!q2.isEmpty()) {
   TreeNode n2 = null;
   if(q1.isEmpty()) {
    n2 = q2.poll();
   }else if(q2.isEmpty()) {
    n2 = new TreeNode(q1.poll());
   }else {
    if(q1.peek()>=q2.peek().val) {
     n2=q2.poll();
    }else {
     n2=new TreeNode(q1.poll());
    }
   }
   if(n1==null) {
    n1=n2;
   }else {
    TreeNode nNode = new TreeNode(n1.val+n2.val);
    nNode.left=n1;
    nNode.right=n2;
    q2.add(nNode);
    n1=null;
   }
  }
  //有頭結點,可以根據需求是否添加頭結點
  root = new TreeNode(0);
  root.right=n1;
  size = vals.size();
 }

帶權路徑長度
WPL = 所有葉子節點的權值與深度-1的乘積之4和

public int getWPL() {
  Queue<TreeNode> queue = new LinkedList<>();
  if(root.right==null) {
   return 0;
  }
  queue.add(root.right);
  int cnt = 1;
  int depth = 0;
  int result = 0;
  while(!queue.isEmpty()) {
   TreeNode node = queue.poll();
   if(node.left!=null) {
    queue.add(node.left);
   }
   if(node.right!=null) {
    queue.add(node.right);
   }
   if(node.right==null&&node.left==null) {
    result+=node.val*depth;
   }
   cnt--;
   if(cnt==0) {
    depth+=1;
    cnt=queue.size();
   }
  }
  return result;
 }

畫圖解釋太麻煩了,就給個鏈接吧
https://mp.weixin.qq.com/s/dMOS7-cTfnhKHs61cUsMpw

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章