【數據結構】-哈夫曼樹以及其應用

哈夫曼樹(Huffman Tree)

1. 哈夫曼樹的定義

哈夫曼樹(Huffman Tree)是一種 帶權路徑長度最短的二叉樹,常用于數據壓縮和最優前綴編碼。其目標是使得 帶權路徑長度(WPL)最小

在信息論和計算機科學中,哈夫曼編碼是一種貪心算法,用于構造哈夫曼樹,以實現最優前綴編碼

2. 哈夫曼樹的構造步驟

構造哈夫曼樹的基本思想是每次選擇當前權值最小的兩個節點合并,形成新的節點,并重復該過程,直到形成一棵樹。

步驟 1:確定權值

假設有如下字符及其權重(頻率):

A(5)  B(9)  C(12)  D(13)  E(16)  F(45)

步驟 2:構造哈夫曼樹

按照如下過程構造哈夫曼樹:

  1. 選取權值最小的兩個節點 A(5)B(9),合并形成新節點 AB(14)
  2. 選取權值最小的兩個節點 C(12)D(13),合并形成新節點 CD(25)
  3. 選取權值最小的兩個節點 AB(14)E(16),合并形成新節點 ABE(30)
  4. 選取權值最小的兩個節點 CD(25)ABE(30),合并形成新節點 CDEAB(55)
  5. 選取最后兩個節點 CDEAB(55)F(45),合并形成最終的哈夫曼樹 Root(100)

步驟 3:生成哈夫曼樹

最終形成的哈夫曼樹如下:

         (100)/      \F(45)     (55)/     \(25)     (30)/    \    /    \C(12) D(13) (14) E(16)/    \A(5)   B(9)

3. 哈夫曼編碼

使用哈夫曼樹生成哈夫曼編碼:

字符編碼
A1100
B1101
C100
D101
E111
F0

哈夫曼編碼的特點:

  • 前綴編碼:任何一個編碼都不是另一個編碼的前綴。
  • 變長編碼:高頻字符使用短編碼,低頻字符使用長編碼。

4. C 語言實現

#include <stdio.h>
#include <stdlib.h>typedef struct Node {char data;int weight;struct Node *left, *right;
} Node;Node* createNode(char data, int weight) {Node* node = (Node*)malloc(sizeof(Node));node->data = data;node->weight = weight;node->left = node->right = NULL;return node;
}void printHuffmanTree(Node* root, char* code, int depth) {if (!root->left && !root->right) {code[depth] = '\0';printf("%c: %s\n", root->data, code);return;}if (root->left) { code[depth] = '0'; printHuffmanTree(root->left, code, depth + 1); }if (root->right) { code[depth] = '1'; printHuffmanTree(root->right, code, depth + 1); }
}

5. 哈夫曼樹的性質

哈夫曼樹具有以下重要性質:

  1. 最優性:哈夫曼樹保證了最短的帶權路徑長度(WPL),即它是最優二叉樹。
  2. 唯一性:給定相同的權值集合,構造的哈夫曼樹是唯一的(可能存在等權子樹的不同組合)。
  3. 前綴編碼:哈夫曼編碼不含有歧義,因為不會出現某個編碼是另一個編碼的前綴。
  4. 貪心策略:哈夫曼算法使用貪心策略,每次合并權值最小的兩個節點,確保局部最優,從而達到全局最優。

6. 哈夫曼樹的應用

哈夫曼樹廣泛應用于數據壓縮、最優前綴編碼、圖像和音頻壓縮等場景。

  • 數據壓縮:如 ZIP、PNG、MP3 等使用哈夫曼編碼減少存儲空間。
  • 信息編碼:在通信系統中,哈夫曼編碼可用于最優數據傳輸。
  • 霍夫曼解碼:使用哈夫曼樹可以有效地解碼壓縮數據。
  • 網絡傳輸:在數據傳輸過程中,哈夫曼編碼減少了帶寬消耗,提高傳輸效率。
  • AI 和機器學習:在特征編碼、模式識別等領域,哈夫曼樹也被廣泛應用。

哈夫曼編碼進行數據壓縮的具體細節

哈夫曼編碼用于數據壓縮的核心思想是利用變長編碼來減少數據存儲空間,高頻字符用短編碼,低頻字符用長編碼,從而降低平均編碼長度。以下是具體細節:


1. 哈夫曼編碼壓縮的基本流程

哈夫曼編碼壓縮數據的流程主要包括構造哈夫曼樹、生成哈夫曼編碼、編碼數據、存儲或傳輸、解碼數據等步驟。

(1)統計字符頻率

在進行壓縮前,首先統計輸入數據中各字符的出現次數。例如,對于字符串 ABRACADABRA,統計出現頻率如下:

字符頻率
A5
B2
R2
C1
D1

(2)構造哈夫曼樹

  1. 將所有字符按照頻率構建成葉子節點
  2. 選取頻率最小的兩個節點合并為一個新節點,并將其頻率設為兩個子節點的頻率之和。
  3. 重復該過程,直到所有節點合并成一棵完整的二叉樹。

示例(簡化版)哈夫曼樹:

        (11)/    \A(5)   (6)/     \B(2)    (4)/     \R(2)   (2)/    \C(1)   D(1)

(3)生成哈夫曼編碼

按照哈夫曼樹,給左子樹賦 0,右子樹賦 1,得到各字符的編碼:

字符哈夫曼編碼
A0
B10
R110
C1110
D1111

(4)編碼數據

將輸入數據轉換為哈夫曼編碼。例如:

原始字符串: ABRACADABRA
哈夫曼編碼: 0 10 110 0 1110 0 1111 0 10 110 0

假設原始數據每個字符占 8-bit,共 11 個字符,總共 88-bit
哈夫曼編碼后,壓縮后數據長度為 26-bit,壓縮率 = 26/88 ≈ 29.5%,大大減少了存儲空間。


(5)存儲或傳輸壓縮數據

編碼后的數據需要存儲或傳輸。由于哈夫曼編碼是變長編碼,解碼時需要哈夫曼樹,因此通常會存儲哈夫曼樹結構或者編碼表,以便解碼。


2. 哈夫曼解碼的過程

解碼時,只需要從哈夫曼樹根節點出發,按二進制流遍歷,遇到葉子節點時即可確定對應字符。例如,解碼 01011001110

0    -> A  
10   -> B  
110  -> R  
0    -> A  
1110 -> C  

還原出的字符串為 ABRAC


3. 哈夫曼編碼在數據壓縮中的應用

哈夫曼編碼在實際應用中廣泛用于無損數據壓縮,包括:

  • 文件壓縮:ZIP、RAR 使用哈夫曼編碼作為部分壓縮算法。
  • 圖片壓縮:PNG 使用哈夫曼編碼進行無損壓縮。
  • 音頻壓縮:MP3、FLAC 采用哈夫曼編碼減少數據存儲量。
  • 視頻編碼:H.264、JPEG 使用哈夫曼編碼壓縮像素信息。
  • 網絡傳輸:HTTP/2 采用 HPACK 算法,其中使用哈夫曼編碼來壓縮頭部數據,提高傳輸效率。

4. 哈夫曼編碼數據壓縮的優缺點

優點:

? 最優前綴編碼,不會產生歧義。
? 無損壓縮,數據不會損壞或丟失。
? 動態適應不同字符頻率,比固定長度編碼更高效。

缺點:

? 需要存儲哈夫曼樹,否則無法解碼。
? 如果字符頻率差別不大,壓縮效果不明顯(如均勻分布的 ASCII 文本)。
? 編碼和解碼速度相對較慢,尤其是在大規模數據上。


5. 結論

哈夫曼編碼是一種高效的無損壓縮算法,在文件、圖片、音視頻等領域被廣泛使用。其核心原理是貪心策略構造最優前綴編碼,使高頻數據占用更少存儲空間,提高壓縮效率。然而,在某些均勻分布的數據集中,其壓縮率可能不如更先進的算法(如 LZ77、LZ78 或 BWT 壓縮)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/897831.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/897831.shtml
英文地址,請注明出處:http://en.pswp.cn/news/897831.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux 命名管道

文章目錄 &#x1f680; 深入理解命名管道&#xff08;FIFO&#xff09;及其C實現一、命名管道核心特性1.1 &#x1f9e9; 基本概念 二、&#x1f4bb; 代碼實現解析2.1 &#x1f4c1; 公共頭文件&#xff08;common.hpp&#xff09;2.2 &#x1f5a5;? 服務器端&#xff08;s…

sap 內存管理與數據共享方式

SAP內存管理 內存是程序之間為了傳遞數據而使用的共享存儲空間 SAP內存分類&#xff1a;1、SAP內存&#xff0c;2、ABAP內存 這兩種內存都是針對同一登錄用戶實現數據共享。 SAP內存&#xff08;SAP Memory&#xff09;和ABAP內存&#xff08;ABAP Memory&#xff09;&…

數據結構與算法(哈希表——兩個數組的交集)

原題 349. 兩個數組的交集 - 力扣&#xff08;LeetCode&#xff09; 給定兩個數組 nums1 和 nums2 &#xff0c;返回 它們的 交集 。輸出結果中的每個元素一定是 唯一 的。我們可以 不考慮輸出結果的順序 。 示例 1&#xff1a; 輸入&#xff1a;nums1 [1,2,2,1], nums2 […

python筆記2

變量&#xff1a;含義 一個容器&#xff0c;計算機當中的存儲空間。 可以理解為一個用于標識或引用數據的名字或標簽。 作用&#xff1a; 可以通過定義一個變量來給需要使用多次的數據命名&#xff0c;就像一個標簽一樣。下次需要使用這個數據時&#xff0c;只需要通過這個變…

【Linux系統編程】信號

目錄 1、信號1.1、什么是信號1.2、進程對信號的處理1.3、信號的生命周期1.4、信號處理流程1.5、信號的發送 2、kill()、raise()函數 發送信號3、alarm函數 鬧鐘信號4、pause函數 掛起信號、暫停5、singal 函數 捕獲信號5.1、為什么返回值是上一次的處理方式5.2、練習 6、sigact…

實用小工具——快速獲取數據庫時間寫法

最近我遇到了一個比較棘手的問題&#xff1a;在工作中&#xff0c;各個項目所使用的數據庫類型各不相同。這導致我習慣性地使用Oracle的SQL語句進行編寫&#xff0c;但每次完成后都會遇到報錯&#xff0c;最終才意識到項目的數據庫并非Oracle。為了避免這種情況&#xff0c;我需…

數據類型及sizeof,進制轉換

其實數據類型可以講很多內容&#xff0c;這里看情況需要講多久吧。 本篇基本都是理論。 目錄 數據類型的分類 基本數據類型 構造數據類型 指針類型 空類型 計算數據類型或變量所占用的內存字節數 基本語法 進制轉換 二進制 二進制的概念 二進制與十進制的轉換 十六進…

pjsip dtmf發送和接收(pjsua)

DTMF(雙音多頻,Dual-Tone Multi-Frequency)是一種用于電話系統的信號技術,通過組合兩個不同頻率的音頻信號來表示數字和符號。以下是DTMF的主要使用背景和應用場景: 電話撥號 DTMF最常見的用途是電話撥號。當用戶按下電話鍵盤上的數字或符號時,電話會生成兩個特定頻率的音…

落雪音樂Pro 8.8.6 | 內置8條音源,無需手動導入,純凈無廣告

洛雪音樂Pro版內置多組穩定音源接口&#xff0c;省去手動導入的繁瑣操作&#xff0c;安裝即可暢聽海量音樂。延續原版無廣告的純凈體驗&#xff0c;支持歌單推薦與音源切換&#xff0c;滿足個性化聽歌需求。此版本僅支持在線播放&#xff0c;無法下載音樂&#xff0c;且與原版不…

mac安裝navicat及使用

0.刪除舊的 sudo rm -Rf /Applications/Navicat\ Premium.app sudo rm -Rf /private/var/db/BootCaches/CB6F12B3-2C14-461E-B5A7-A8621B7FF130/app.com.prect.NavicatPremium.playlist sudo rm -Rf ~/Library/Caches/com.apple.helpd/SDMHelpData/Other/English/HelpSDMIndexF…

【Unity】 HTFramework框架(六十二)Agent編輯器通用智能體(AI Agent)

更新日期&#xff1a;2025年3月14日。 Github源碼&#xff1a;[點我獲取源碼] Gitee源碼&#xff1a;[點我獲取源碼] 索引 編輯器通用智能體AIAgent類Friday&#xff08;星期五&#xff09;啟用智能體設置智能體類型開放智能體權限智能體交互資源優化批處理運行代碼聯網搜索休閑…

EverArt MCP 服務器安裝調試筆記 -cline

EverArt MCP 服務器安裝調試筆記 問題描述 用戶在使用 EverArt MCP 服務器時遇到報錯&#xff1a;“MCP error -1: Connection closed”。 調試過程 檢查配置文件 cline_mcp_settings.json: 確認 everart 服務器的配置信息&#xff0c;包括 command、args 和 env 是否正確。…

MFC中使用Create或CreateDialog創建對話框失敗,GetLastError錯誤碼為1813(找不到映像文件中指定的資源類型)

文章目錄 創建對話框失敗示例、原因分析及解決方案示例代碼錯誤原因解決方案 AFX_MANAGE_STATE(AfxGetStaticModuleState())作用一、功能1. 模塊狀態切換2. 自動狀態恢復 二、為什么要用該函數&#xff1f;三、必須使用該宏的典型場景1. MFC 擴展 DLL&#xff08;Extension DLL…

php進程管理

php-fpm(fastcgi process manager)是PHP 的FastCGI管理器&#xff0c;管理PHP的FastCGI進程&#xff0c;提升PHP應用的性能和穩定性 php-fpm是一個高性能的php FastCGI管理器&#xff0c;提供了更好的php進程管理方式&#xff0c;可以有效的控制內存和進程&#xff0c;支持平滑…

《MySQL數據庫從零搭建到高效管理|表的增刪改查(基礎)》

目錄 引言&#xff1a; 一、表的操作 1.1 創建學生表 1.2 查看表結構 1.3 刪除表 1.4 修改表名 1.5 添加字段 1.6 修改字段 1.7 刪除字段 1.8 小結 二、CRUD 2.1 新增&#xff08;Create&#xff09;數據 2.2 查詢&#xff08;Retrieve&#xff09;數據 2.3 修改&…

建筑管理(2): 施工承包模式,工程監理,質量監督

文章目錄 一. 施工承包模式1. 施工總承包模式1.1 施工總承包的特點1.2 施工總承包模式中的承包方 2. 平行承包模式3. 聯合體與合作體承包模式 二. 工程監理1. 強制實行監理的工程范圍1.1 國家重點建設工程1.2 大中型公用事業工程(重點)1.3 成片開發建設的住宅小區工程1.4 必須實…

Spring Boot與Apache Ignite集成:構建高性能分布式緩存和計算平臺

1. 前言 1.1 什么是Apache Ignite Apache Ignite是一個高性能的分布式內存計算平臺,支持內存緩存、分布式計算、流處理和機器學習等功能。它提供了低延遲的數據訪問和強大的計算能力,適用于需要高性能和可擴展性的應用。 1.2 為什么選擇Apache Ignite 高性能:Ignite利用內…

REST 請求返回 Invalid Credentials

REST 請求返回 “Invalid Credentials”&#xff08;無效憑據&#xff09;&#xff0c;通常表示身份驗證失敗。可能的原因和解決方案如下&#xff1a; 可能的原因 & 解決方案 用戶名或密碼錯誤 確保使用正確的用戶名和密碼。如果 API 需要 Base64 編碼的 Authorization 頭…

C++Primer學習(6.7 函數指針——難!)

6.7 函數指針 (這一章節比較難) 函數指針指向的是函數而非對象。和其他指針一樣&#xff0c;函數指針指向某種特定類型。函數的類型由它的返回類型和形參類型共同決定&#xff0c;與函數名無關。例如: //比較兩個 string 對象的長度 bool lengthCompare(const string &,co…

高級java每日一道面試題-2025年2月26日-框架篇[Mybatis篇]-Mybatis是如何將sql執行結果封裝為目標對象并返回的?都有哪些映射形式 ?

如果有遺漏,評論區告訴我進行補充 面試官: Mybatis是如何將sql執行結果封裝為目標對象并返回的?都有哪些映射形式 ? 我回答: 在Java高級面試中討論MyBatis如何將SQL執行結果封裝為目標對象并返回的過程時&#xff0c;我們可以從過程細節和映射形式兩個方面來綜合解答這個問…