国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

數據結構-構造哈夫曼樹【詳解+代碼+圖示】一文解惑!

這篇具有很好參考價值的文章主要介紹了數據結構-構造哈夫曼樹【詳解+代碼+圖示】一文解惑!。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

哈夫曼樹 (Huffman Tree)

導論

我們在學習哈夫曼樹之前需要先了解 什么是哈夫曼樹?

  • 哈夫曼樹 是一種最優(yōu)樹,是一類帶權路徑長度最短的二叉樹,通過哈夫曼算法可以構建一棵哈夫曼樹,利用哈夫曼樹可以構造一種不等長的二進制編碼,并且構造所得的哈夫曼編碼是一種最優(yōu)前綴碼.

  • 通俗來講 : n 個帶權節(jié)點均作為葉子節(jié)點,構造出的一棵帶權路徑長度最短的二叉樹,則把這棵樹稱為"哈夫曼樹" 、“赫夫曼樹” 、“Huffman Tree” 或者 “最優(yōu)二叉樹” . (備注 : 本文均用 “哈夫曼樹” 來稱呼)


第一次接觸 哈夫曼樹 的小伙伴可能對上述的定義不能第一時間消化,我們可以先來明確幾個學哈夫曼樹之前必須掌握的幾個會用到的名詞的概念,把這幾個概念理解透了之后會幫助你更好的認識哈夫曼樹.

  • 路徑: 在一棵樹中 ,從一個結點到另外一個結點的通路就稱為 樹的路徑 .如圖1.1 從根節(jié)點root到D節(jié)點之間的通路就是二叉樹中的一條路徑
  • 路徑長度 : 在路徑中,每經過一個結點路徑長度就加一 .如果我們規(guī)定根節(jié)點所在的樹的 層數為第一層,那么從根節(jié)點出發(fā) 走到第 i 層 ,那么當前層的節(jié)點的 路徑長度 等于 i-1,如圖1.1所示
  • 樹的路徑長度 : 從根節(jié)點出發(fā)到所有結點的路徑長度之和.
  • 結點的權值 : ?一個結點的權值實際上就是這個結點子樹在整個樹中所占的比例. 如圖1.1 所示 ,C、A、D、B、E結點的權分別為2、5、9、6、7.
  • 結點的帶權路徑長度 : 結點到樹根之間的路徑長度與該結點權值的乘積.如圖1.1 所示 ,D結點的帶權路徑長度 = 2 * 9 = 18
  • 樹的帶權路徑長度 ( Weighted Path Length of Tree 簡稱為 WPL): 樹中所有葉子結點的帶權路徑長度之和.如圖1.1 所示,該哈夫曼樹的帶權路徑長度 WPL =2 * 3 + 5 * 3 + 9 * 2 + 6 * 2 + 7 * 2 = 65
    數據結構哈夫曼樹存儲結構ht的終態(tài)填寫步驟,數據結構,數據結構,算法,java,霍夫曼樹
    數據結構哈夫曼樹存儲結構ht的終態(tài)填寫步驟,數據結構,數據結構,算法,java,霍夫曼樹

構造哈夫曼樹

要記住 哈夫曼樹 中的權值越大的結點離根節(jié)點越近,權值越小的結點離根節(jié)點越遠,這意味著一組帶權結點構造出來的哈夫曼樹中權值最小的結點離哈夫曼樹最遠,權值最大的結點離哈夫曼樹最近,也就是我們 圖1.1 中可以觀察出來的.

構造哈夫曼樹的過程其實就是"爸爸去哪兒"的過程.

語言描繪

  • 形象敘述構造哈夫曼樹的步驟

    從下往上構造,從已知的剩余權值集合中權值最小的那兩個結點(如果權值相同那么直接就是相同的這兩個結點),讓他們成為兄弟結點,兩兄弟的權值相加,合力找到父親結點,此時父親節(jié)點的權值就是兩兄弟結點的權值的和,然后把父親節(jié)點的權值添加到權值集合中的同時刪除這兩個兄弟節(jié)點,.重復循環(huán)"爸爸去哪兒"這個過程,直至權值集合中只剩下祖宗(根節(jié)點)為止. 那么這棵哈夫曼樹也就構造完了.

    備注: 感覺核心就是你現在計劃創(chuàng)建一棵二叉樹,但是這棵二叉樹你不能隨意創(chuàng)建,而是要按照生成 “最優(yōu)二叉樹” 的規(guī)則來創(chuàng)建 ,這樣想是不是就簡單許多 ! 而這個規(guī)則就是哈夫曼算法.


  • 嚴謹的構造哈夫曼樹的步驟

對于給定的有各自權值的 n 個結點

  1. 在 n 個權值中選出兩個最小的權值,對應的兩個結點組成一個新的二叉樹,且新二叉樹的根結點的權值為左右孩子權值的和;
  2. 在原有的 n 個權值中刪除那兩個最小的權值,同時將新的權值加入到 n–2 個權值的行列中,以此類推;
  3. 重復 1 和 2 ,直到所以的結點構建成了一棵二叉樹為止,這棵樹就是哈夫曼樹/最優(yōu)二叉樹。

注意:

  1. 最優(yōu)二叉樹的形態(tài)不唯一,但是WPL最小.
  2. 最優(yōu)二叉樹中,權越大的葉子離根越近.

圖形化理解

例如: 已知權值 W = {2,5,9,6,7},請構造哈夫曼樹.

數據結構哈夫曼樹存儲結構ht的終態(tài)填寫步驟,數據結構,數據結構,算法,java,霍夫曼樹


證明結論

最優(yōu)二叉樹的形態(tài)不唯一,但是WPL最小

  • 先證明第一句話: 相同的權值構造出來的哈夫曼樹形態(tài)不唯一

同樣是上述的例子,我們可以構造出另一種形態(tài)的哈夫曼樹,同時我們可以計算出兩種形態(tài)的二叉樹的帶權路徑,看看是否相等 ?

數據結構哈夫曼樹存儲結構ht的終態(tài)填寫步驟,數據結構,數據結構,算法,java,霍夫曼樹


  • 然后我們來證明第二句話 : 證明哈夫曼算法構造出的哈夫曼樹的WPL一定是最小的,且其他二叉樹的WPL一定大于等于哈夫曼樹的WPL。

1. 定義:

  • 帶權路徑長度(WPL)是指每個葉子節(jié)點的權值乘以其深度的總和。

2. 引理:

  • 對于任意的二叉樹,交換任意兩個葉子節(jié)點的位置,WPL都會增加。

3. 證明:

  • 哈夫曼樹的構造過程

    1. 哈夫曼算法每次選擇權值最小的兩個節(jié)點合并,構造出一顆二叉樹。
    2. 重復這個過程,直到所有節(jié)點合并成一個根節(jié)點,形成哈夫曼樹。
  • 交換葉子節(jié)點的影響

    • 考慮哈夫曼樹的構造過程,每次選擇最小的兩個節(jié)點合并,如果我們交換了兩個葉子節(jié)點的位置,這兩個節(jié)點的權值就不再是最小的了。
    • 在構造過程中,我們總是選擇權值最小的節(jié)點,因此交換葉子節(jié)點位置后,這兩個節(jié)點的合并會在構造樹的過程中晚一些,導致它們在更深的層次上,從而增加了WPL。

    如果這里不懂這里的影響是什么,我會再下一篇的博客中詳細解釋,這涉及到了 貪心策略

  • 結論

    • 由于哈夫曼算法保證了每次合并都選擇最小權值的節(jié)點,任何對于葉子節(jié)點位置的交換都會導致合并發(fā)生在更深的層次上,增加WPL。
    • 因此,哈夫曼樹的構造方式保證了WPL最小。

4. 總結:

  • 哈夫曼樹的構造方式保證了每次合并都是最優(yōu)的選擇,從而使得整個樹的WPL最小。
  • 如果使用其他方式構造二叉樹,由于不能保證每次都選擇最小權值的節(jié)點進行合并,可能會導致WPL更大。

代碼實現

在構造哈夫曼樹的過程中,我們首先需要定義一個節(jié)點類來表示樹的節(jié)點,然后編寫一個構造哈夫曼樹的算法。

  1. 定義了一個HuffmanNode類,用于表示哈夫曼樹的節(jié)點
  2. HuffmanTree類中,實現一個buildHuffmanTree方法,該方法接受一個權值數組
  3. 使用優(yōu)先隊列來構造哈夫曼樹
  4. 通過main方法演示了如何使用這個方法來構造哈夫曼樹

這個實現涉及到了優(yōu)先隊列(PriorityQueue),它是一個能夠保證每次取出的元素都是隊列中權值最小的元素的數據結構。在哈夫曼樹的構建中,我們不斷地合并權值最小的兩個節(jié)點,而優(yōu)先隊列正好能夠滿足這個需求。

package src.test.java;

import java.util.PriorityQueue;

// 定義哈夫曼樹節(jié)點類
class HuffmanNode implements Comparable<HuffmanNode> {
    int weight;          // 權值
    HuffmanNode left;    // 左子節(jié)點
    HuffmanNode right;   // 右子節(jié)點

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

    // 實現Comparable接口,用于PriorityQueue的比較
    @Override
    public int compareTo(HuffmanNode other) {
        return this.weight - other.weight;
    }
}

public class HuffmanTree {

    // 構造哈夫曼樹的方法
    public static HuffmanNode buildHuffmanTree(int[] weights) {
        // 使用優(yōu)先隊列來存儲節(jié)點,每次都取出權值最小的兩個節(jié)點進行合并
        PriorityQueue<HuffmanNode> pq = new PriorityQueue<>();
        
        // 將權值數組中的每個元素轉化為節(jié)點并添加到優(yōu)先隊列中
        for (int weight : weights) {
            pq.add(new HuffmanNode(weight));
        }

        // 不斷合并節(jié)點直到只剩一個節(jié)點,即哈夫曼樹的根節(jié)點
        while (pq.size() > 1) {
            HuffmanNode left = pq.poll();   // 彈出權值最小的節(jié)點
            HuffmanNode right = pq.poll();  // 彈出權值次小的節(jié)點

            // 創(chuàng)建一個新節(jié)點,權值為兩個子節(jié)點的權值之和
            HuffmanNode parent = new HuffmanNode(left.weight + right.weight);
            parent.left = left;
            parent.right = right;

            // 將新節(jié)點添加回優(yōu)先隊列
            pq.add(parent);
        }

        // 返回哈夫曼樹的根節(jié)點
        return pq.poll();
    }

    // 打印哈夫曼樹的方法(可選)
    public static void printHuffmanTree(HuffmanNode root, String prefix) {
        if (root != null) {
            System.out.println(prefix + root.weight);
            printHuffmanTree(root.left, prefix + "0");
            printHuffmanTree(root.right, prefix + "1");
        }
    }

    public static void main(String[] args) {
        int[] weights = {2, 5, 9, 6, 7};

        // 構造哈夫曼樹
        HuffmanNode root = buildHuffmanTree(weights);

        // 打印哈夫曼樹(可選)
        printHuffmanTree(root, "");
    }
}


測試

package src.test.java;

public class HuffmanTreeTest {

    public static void main(String[] args) {
        int[] weights = {2, 5, 9, 6, 7};

        // 構造哈夫曼樹
        HuffmanNode root = HuffmanTree.buildHuffmanTree(weights);

        // 打印哈夫曼樹的結構
        System.out.println("Huffman Tree Structure:");
        printHuffmanTreeStructure(root, "");
    }

    // 遞歸打印哈夫曼樹的結構
    private static void printHuffmanTreeStructure(HuffmanNode root, String prefix) {
        if (root != null) {
            System.out.println(prefix + "Weight: " + root.weight);
            if (root.left != null || root.right != null) {
                System.out.println(prefix + "├── Left:");
                printHuffmanTreeStructure(root.left, prefix + "│    ");
                System.out.println(prefix + "└── Right:");
                printHuffmanTreeStructure(root.right, prefix + "     ");
            }
        }
    }
}

結果對照

  • 控制臺輸出結果

數據結構哈夫曼樹存儲結構ht的終態(tài)填寫步驟,數據結構,數據結構,算法,java,霍夫曼樹

  • 哈夫曼樹圖形

數據結構哈夫曼樹存儲結構ht的終態(tài)填寫步驟,數據結構,數據結構,算法,java,霍夫曼樹


總結

  1. 基礎概念:深入了解了哈夫曼樹的概念,包括路徑、路徑長度、帶權路徑長度等基礎知識。

  2. 構造過程:通過圖形化和語言描述,清晰演示了從下而上構造哈夫曼樹的步驟,以及最終得到最優(yōu)二叉樹的過程。

  3. 證明方法:通過引理和推導,解釋了為何哈夫曼樹的構造方式能夠保證帶權路徑長度最小,涉及到了貪心策略的應用。

  4. 實際應用:通過Java代碼實現展示了哈夫曼樹的構造過程,將理論知識轉化為實際應用,加深了對算法的理解。

    數據結構哈夫曼樹存儲結構ht的終態(tài)填寫步驟,數據結構,數據結構,算法,java,霍夫曼樹文章來源地址http://www.zghlxwxcb.cn/news/detail-761848.html

到了這里,關于數據結構-構造哈夫曼樹【詳解+代碼+圖示】一文解惑!的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 數據結構課程實驗五:哈夫曼樹與哈夫曼編碼

    實驗日期:2022-12-20 ? 目錄 一、實驗目的 1、掌握哈夫曼樹的建立 2、掌握哈夫曼編碼方式 二、實驗內容

    2024年02月05日
    瀏覽(30)
  • 【數據結構與算法】-哈夫曼樹(Huffman Tree)與哈夫曼編碼

    【數據結構與算法】-哈夫曼樹(Huffman Tree)與哈夫曼編碼

    超詳細講解哈夫曼樹(Huffman Tree)以及哈夫曼編碼的構造原理、方法,并用代碼實現。 路徑 :從樹中一個結點到另一個結點之間的 分支 構成這兩個結點間的路徑。 結點的路徑長度 :兩結點間路徑上的 分支數 。 樹的路徑長度: 從樹根到每一個結點的路徑長度之和。記作: TL? 權

    2024年02月06日
    瀏覽(19)
  • 數據結構【哈夫曼樹】

    數據結構【哈夫曼樹】

    最優(yōu)二叉樹也稱哈夫曼 (Huffman) 樹 ,是指對于一組帶有確定權值的葉子結點,構造的具有最小帶權路徑長度的二叉樹。權值是指一個與特定結點相關的數值。哈夫曼樹是帶權路徑長度最短的樹,權值較大的結點離根較近。 涉及到的幾個概念: 路徑: 從樹中一個結點到另一個結

    2024年02月14日
    瀏覽(22)
  • 數據結構-哈夫曼樹

    數據結構-哈夫曼樹

    介紹 哈夫曼樹,指 帶權路徑長度最短的二叉樹 ,通常用于數據壓縮中 什么是帶權路徑長度? 假設有一個結點,我們?yōu)樗x值,這個值我們稱為權值,那么從根結點到它所在位置,所經歷的路徑,與這個權值的積,就是它的帶權路徑長度。 比如有這樣一棵樹,D權值為2 ?從

    2024年02月20日
    瀏覽(22)
  • 數據結構----哈夫曼樹

    數據結構----哈夫曼樹

    哈夫曼樹就是尋找構造最優(yōu)二叉樹,用于提高效率 各種路徑長度 各種帶權路徑長度 結點的帶權路徑長度 樹的帶權路徑長度 哈夫曼樹 帶權路徑長度最短的樹或者二叉樹 也就是樹的葉子結點帶權路徑長度之和 :也就是葉子結點的結點路徑長度(根結點到葉子結點的路徑數)

    2024年01月21日
    瀏覽(23)
  • 【數據結構實驗】哈夫曼樹

    為一個信息收發(fā)站編寫一個哈夫曼碼的編/譯碼系統(tǒng)。文末貼出了源代碼。 完整的系統(tǒng)需要具備完整的功能,包含初始化、編碼、譯碼、印代碼文件和印哈夫曼樹,因此需要進行相應的文件操作進行配合。 哈夫曼樹的字符集和頻度可以從文件中讀入,也可以讓用戶手動輸入,

    2023年04月22日
    瀏覽(18)
  • 【數據結構-樹】哈夫曼樹

    【數據結構-樹】哈夫曼樹

    ??????歡迎來到我的博客,很高興能夠在這里和您見面!希望您在這里可以感受到一份輕松愉快的氛圍,不僅可以獲得有趣的內容和知識,也可以暢所欲言、分享您的想法和見解。 推薦:kuan 的首頁,持續(xù)學習,不斷總結,共同進步,活到老學到老 導航 檀越劍指大廠系列:全面總

    2024年02月08日
    瀏覽(20)
  • 數據結構—哈夫曼樹及其應用

    數據結構—哈夫曼樹及其應用

    5.6哈夫曼樹及其應用 5.6.1哈夫曼樹的基本概念 路徑 :從樹中一個結點到另一個結點之間的 分支 構成這兩個結點間的路徑。 結點的路徑長度 :兩結點間路徑上的 分支數 。 樹的路徑長度 :從 樹根 到每一個結點的 路徑長度之和 。記作 TL 結點數目相同的二叉樹中,完全二叉

    2024年02月14日
    瀏覽(18)
  • 【數據結構】實驗十:哈夫曼編碼

    【數據結構】實驗十:哈夫曼編碼

    實驗十?哈夫曼編碼 一、實驗目的與要求 1 )掌握樹、森林與二叉樹的轉換; 2 )掌握哈夫曼樹和哈夫曼編碼算法的實現; 二、?實驗內容 1.? 請編程實現如圖所示的樹轉化為二叉樹。 2.? 編程實現一個哈夫曼編碼系統(tǒng),系統(tǒng)功能包括: (1)? 字符信息統(tǒng)計:讀取待編碼的源文

    2024年02月15日
    瀏覽(19)
  • 數據結構與算法--哈夫曼樹應用

    第1關:統(tǒng)計報文中各個字符出現的次數 任務描述 本關任務: 給定一串文本,統(tǒng)計其中各個字符出現的次數; 測試說明 平臺會對你編寫的代碼進行測試: 測試輸入:` abcdeabcdeabcdabcdabcdabcbccc 預期輸出: a 6 b 7 c 9 d 5 e 2 代碼: 第2關:對第一關報文中的各個字符進行哈夫曼編

    2024年02月06日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包