在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Huffman壓縮算法概述和詳細(xì)流程

FPGA開源工作室 ? 來(lái)源:FPGA開源工作室 ? 2024-10-21 13:48 ? 次閱讀

1 概述

Huffman壓縮算法是一種基于字符出現(xiàn)頻率的編碼算法,通過(guò)構(gòu)建Huffman樹,將出現(xiàn)頻率高的字符用短編碼表示,出現(xiàn)頻率低的字符用長(zhǎng)編碼表示,從而實(shí)現(xiàn)對(duì)數(shù)據(jù)的壓縮。以下是Huffman壓縮算法的詳細(xì)流程:
統(tǒng)計(jì)字符頻率:遍歷待壓縮的數(shù)據(jù),統(tǒng)計(jì)每個(gè)字符出現(xiàn)的頻率。
構(gòu)建優(yōu)先隊(duì)列:將每個(gè)字符及其頻率作為一個(gè)結(jié)點(diǎn)放入優(yōu)先隊(duì)列(或最小堆)中,根據(jù)字符頻率構(gòu)建一個(gè)按頻率大小排序的優(yōu)先隊(duì)列。
構(gòu)建Huffman樹:不斷地從優(yōu)先隊(duì)列中取出頻率最小的兩個(gè)結(jié)點(diǎn),合并為一個(gè)新結(jié)點(diǎn),并將新結(jié)點(diǎn)重新插入到優(yōu)先隊(duì)列中,直到隊(duì)列只剩下一個(gè)結(jié)點(diǎn),即Huffman樹的根結(jié)點(diǎn)。
生成Huffman編碼:通過(guò)遍歷Huffman樹,從根結(jié)點(diǎn)到每個(gè)葉子結(jié)點(diǎn)的路徑上的左右分支分別對(duì)應(yīng)編碼0和1,根據(jù)路徑生成每個(gè)字符的Huffman編碼。
壓縮數(shù)據(jù):根據(jù)生成的Huffman編碼,將待壓縮數(shù)據(jù)中的每個(gè)字符替換為對(duì)應(yīng)的Huffman編碼,得到壓縮后的數(shù)據(jù)。
存儲(chǔ)壓縮表:將字符與對(duì)應(yīng)的Huffman編碼關(guān)系存儲(chǔ)為壓縮表,以便解壓縮時(shí)使用。
存儲(chǔ)壓縮數(shù)據(jù):將壓縮后的數(shù)據(jù)以二進(jìn)制形式存儲(chǔ)。
在解壓縮時(shí),需要根據(jù)存儲(chǔ)的Huffman編碼表和壓縮數(shù)據(jù),使用相同的Huffman樹結(jié)構(gòu)進(jìn)行解碼,將壓縮數(shù)據(jù)解壓縮成原始數(shù)據(jù),并輸出原始數(shù)據(jù)。
Huffman壓縮算法的優(yōu)勢(shì)在于可以根據(jù)數(shù)據(jù)的特征自適應(yīng)地確定編碼,使得出現(xiàn)頻率高的字符擁有更短的編碼,從而實(shí)現(xiàn)高效的數(shù)據(jù)壓縮。然而,Huffman算法對(duì)于小規(guī)模數(shù)據(jù)壓縮效果不佳,適用于處理較大規(guī)模的數(shù)據(jù)壓縮。

2 huffman壓縮算法過(guò)程詳細(xì)演示

下面將通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)演示Huffman壓縮算法的壓縮過(guò)程,假設(shè)有一個(gè)字符串 “ABRACADABRA” 需要進(jìn)行壓縮。

統(tǒng)計(jì)字符頻率:

A: 5 次
B: 2 次
R: 2 次
C: 1 次
D: 1 次
2) 構(gòu)建優(yōu)先隊(duì)列:
構(gòu)建一個(gè)優(yōu)先隊(duì)列,按照字符頻率排序:

(C, 1), (D, 1), (B, 2), (R, 2), (A, 5)
3) 構(gòu)建Huffman樹:
不斷地從優(yōu)先隊(duì)列中取出頻率最小的兩個(gè)結(jié)點(diǎn),合并為一個(gè)新節(jié)點(diǎn),并重新插入隊(duì)列中,直到隊(duì)列只剩下一個(gè)節(jié)點(diǎn),作為Huffman樹的根節(jié)點(diǎn)。

合并過(guò)程:

(C, 1)和(D, 1) -> (CD, 2)
(B, 2)和(R, 2) -> (BR, 4)
((CD, 2) 和 (BR, 4)) -> ((CD)BR, 6)
((A, 5) 和 ((CD)BR, 6)) -> (((CD)BR)A, 11)
最終得到的Huffman樹如下:
(((CD)BR)A)
/
(CD)BR A
/
CD BR
/ /
C D B R

生成Huffman編碼:
從根節(jié)點(diǎn)開始,左分支為0,右分支為1,生成每個(gè)字符的Huffman編碼:

A: 0
B: 101
R: 100
C: 1100
D: 1101
6) 壓縮數(shù)據(jù):
將原始數(shù)據(jù)字符串 “ABRACADABRA” 中的每個(gè)字符使用對(duì)應(yīng)的Huffman編碼替換,得到壓縮后的數(shù)據(jù)。

原始數(shù)據(jù):ABRACADABRA
Huffman編碼:010110011001011010001011110
壓縮后數(shù)據(jù):010110011001011010001011110

在實(shí)際壓縮過(guò)程中,還需要將Huffman編碼表(字符與編碼的映射關(guān)系)一并存儲(chǔ),以便在解壓縮時(shí)使用。通過(guò)上述過(guò)程,原始數(shù)據(jù)被成功壓縮,并且根據(jù)Huffman編碼,高頻字符編碼較短,低頻字符編碼較長(zhǎng),實(shí)現(xiàn)了數(shù)據(jù)的有效壓縮。

3 c語(yǔ)言Huffman壓縮代碼示例

以下是一個(gè)簡(jiǎn)單的C語(yǔ)言示例代碼,實(shí)現(xiàn)了Huffman算法進(jìn)行數(shù)據(jù)壓縮和解壓縮的功能:

#include 
#include 
#include 

#define MAX_TREE_HT 100

// 結(jié)點(diǎn)結(jié)構(gòu)體
typedef struct MinHeapNode {
    char data;
    unsigned freq;
    struct MinHeapNode *left, *right;
} MinHeapNode;

// 最小堆結(jié)構(gòu)體
typedef struct MinHeap {
    unsigned size;
    unsigned capacity;
    MinHeapNode **array;
} MinHeap;

// 創(chuàng)建新結(jié)點(diǎn)
MinHeapNode* newNode(char data, unsigned freq) {
    MinHeapNode* node = (MinHeapNode*)malloc(sizeof(MinHeapNode));
    node->left = node->right = NULL;
    node->data = data;
    node->freq = freq;
    return node;
}

// 創(chuàng)建最小堆
MinHeap* createMinHeap(unsigned capacity) {
    MinHeap* minHeap = (MinHeap*)malloc(sizeof(MinHeap));
    minHeap->size = 0;
    minHeap->capacity = capacity;
    minHeap->array = (MinHeapNode**)malloc(minHeap->capacity * sizeof(MinHeapNode*));
    return minHeap;
}

// 交換兩個(gè)結(jié)點(diǎn)
void swapMinHeapNodes(MinHeapNode** a, MinHeapNode** b) {
    MinHeapNode* t = *a;
    *a = *b;
    *b = t;
}

// 最小堆調(diào)整
void minHeapify(MinHeap* minHeap, int idx) {
    int smallest = idx;
    int left = 2 * idx + 1;
    int right = 2 * idx + 2;

    if (left < minHeap->size && minHeap->array[left]->freq < minHeap->array[smallest]->freq)
        smallest = left;

    if (right < minHeap->size && minHeap->array[right]->freq < minHeap->array[smallest]->freq)
        smallest = right;

    if (smallest != idx) {
        swapMinHeapNodes(&minHeap->array[smallest], &minHeap->array[idx]);
        minHeapify(minHeap, smallest);
    }
}

// 獲取最小結(jié)點(diǎn)
MinHeapNode* extractMin(MinHeap* minHeap) {
    MinHeapNode* temp = minHeap->array[0];
    minHeap->array[0] = minHeap->array[minHeap->size - 1];
    --minHeap->size;
    minHeapify(minHeap, 0);
    return temp;
}

// 插入結(jié)點(diǎn)
void insertMinHeap(MinHeap* minHeap, MinHeapNode* minHeapNode) {
    ++minHeap->size;
    int i = minHeap->size - 1;
    while (i && minHeapNode->freq < minHeap->array[(i - 1) / 2]->freq) {
        minHeap->array[i] = minHeap->array[(i - 1) / 2];
        i = (i - 1) / 2;
    }
    minHeap->array[i] = minHeapNode;
}

// 創(chuàng)建和構(gòu)建最小堆
MinHeap* buildMinHeap(char data[], int freq[], int size) {
    MinHeap* minHeap = createMinHeap(size);
    for (int i = 0; i < size; ++i)
        minHeap->array[i] = newNode(data[i], freq[i]);
    minHeap->size = size;
    
    for (int i = size / 2 - 1; i >= 0; --i)
        minHeapify(minHeap, i);
    
    return minHeap;
}

// 檢查結(jié)點(diǎn)是否是葉子結(jié)點(diǎn)
int isLeaf(MinHeapNode* root) {
    return !(root->left) && !(root->right);
}

// 構(gòu)建霍夫曼樹
MinHeapNode* buildHuffmanTree(char data[], int freq[], int size) {
    MinHeapNode *left, *right, *top;
    MinHeap* minHeap = buildMinHeap(data, freq, size);

    while (minHeap->size != 1) {
        left = extractMin(minHeap);
        right = extractMin(minHeap);
        top = newNode('$', left->freq + right->freq);
        top->left = left;
        top->right = right;
        insertMinHeap(minHeap, top);
    }

    return extractMin(minHeap);
}

// 打印霍夫曼編碼
void printCodes(MinHeapNode* root, int arr[], int top) {
    if (root->left) {
        arr[top] = 0;
        printCodes(root->left, arr, top + 1);
    }

    if (root->right) {
        arr[top] = 1;
        printCodes(root->right, arr, top + 1);
    }

    if (isLeaf(root)) {
        printf("%c: ", root->data);
        for (int i = 0; i < top; ++i)
            printf("%d", arr[i]);
        printf("
");
    }
}

// 壓縮數(shù)據(jù)
void huffmanCompression(char data[]) {
    int freq[256] = {0};
    int n = strlen(data);
    for (int i = 0; i < n; ++i)
        ++freq[data[i]];

    char arr[256];
    int freq2[256];
    int size = 0;
    
    for (int i = 0; i < 256; ++i) {
        if (freq[i] != 0) {
            arr[size] = (char)i;
            freq2[size] = freq[i];
            ++size;
        }
    }

    MinHeapNode* root = buildHuffmanTree(arr, freq2, size);
    int arr2[MAX_TREE_HT], top = 0;
    printCodes(root, arr2, top);
}

int main() {
    char data[] = "hello world";
    huffmanCompression(data);
    
    return 0;
}

這個(gè)示例代碼演示了使用Huffman算法對(duì)輸入的數(shù)據(jù)進(jìn)行壓縮,并打印出各個(gè)字符的Huffman編碼。huffmanCompression 函數(shù)首先統(tǒng)計(jì)輸入數(shù)據(jù)中每個(gè)字符的出現(xiàn)頻率,并構(gòu)建Huffman樹,然后通過(guò)遞歸遍歷Huffman樹獲取每個(gè)字符的Huffman編碼并打印出來(lái)。在 main 函數(shù)中,我們對(duì)一個(gè)簡(jiǎn)單的字符串進(jìn)行了壓縮,并輸出了每個(gè)字符的Huffman編碼。

需要注意的是,這個(gè)示例代碼僅演示了Huffman算法的基本壓縮原理,實(shí)際應(yīng)用中可能需要對(duì)數(shù)據(jù)內(nèi)容、編碼方式等進(jìn)行更多處理和優(yōu)化。

4 C語(yǔ)言Huffman解壓縮算法示例

以下是一個(gè)簡(jiǎn)單的C語(yǔ)言示例代碼,實(shí)現(xiàn)了Huffman算法進(jìn)行數(shù)據(jù)解壓縮的功能:

#include 
#include 
#include 

// 結(jié)點(diǎn)結(jié)構(gòu)體
typedef struct MinHeapNode {
    char data;
    struct MinHeapNode *left, *right;
} MinHeapNode;

// 解壓縮數(shù)據(jù)
void huffmanDecompression(char data[], MinHeapNode* root) {
    int n = strlen(data);
    MinHeapNode* current = root;
    
    for (int i = 0; i < n; ++i) {
        if (data[i] == '0') {
            current = current->left;
        } else {
            current = current->right;
        }

        if (current->left == NULL && current->right == NULL) {
            printf("%c", current->data);
            current = root;
        }
    }
}

int main() {
    // 構(gòu)造Huffman樹
    MinHeapNode *root = (MinHeapNode*)malloc(sizeof(MinHeapNode));
    root->left = root->right = NULL;

    MinHeapNode *A = (MinHeapNode*)malloc(sizeof(MinHeapNode));
    A->data = 'A';
    A->left = A->right = NULL;

    MinHeapNode *B = (MinHeapNode*)malloc(sizeof(MinHeapNode));
    B->data = 'B';
    B->left = B->right = NULL;

    MinHeapNode *C = (MinHeapNode*)malloc(sizeof(MinHeapNode));
    C->data = 'C';
    C->left = C->right = NULL;

    root->left = A;
    root->right = B;
    A->left = C;
    A->right = NULL;
    B->left = B->right = NULL;
    C->left = C->right = NULL;

    // 待解壓縮的數(shù)據(jù)
    char data[] = "00100110001";

    // 解壓縮數(shù)據(jù)
    huffmanDecompression(data, root);
    
    return 0;
}

在這個(gè)簡(jiǎn)單的示例代碼中,我們首先構(gòu)建了一個(gè)簡(jiǎn)單的Huffman樹,然后定義了一個(gè)待解壓縮的數(shù)據(jù)字符串。huffmanDecompression 函數(shù)接受壓縮后的數(shù)據(jù)和Huffman樹的根結(jié)點(diǎn)作為參數(shù),通過(guò)逐位解析壓縮后的數(shù)據(jù),按照Huffman樹逐步走到葉子結(jié)點(diǎn),從而解壓縮出原始數(shù)據(jù)并打印。

在 main 函數(shù)中,我們構(gòu)造了一個(gè)簡(jiǎn)單的Huffman樹,并指定了一個(gè)簡(jiǎn)單的待解壓縮的數(shù)據(jù)字符串,然后調(diào)用 huffmanDecompression 函數(shù)進(jìn)行解壓縮操作。解壓縮過(guò)程中,輸出的字符序列應(yīng)該是根據(jù)Huffman樹進(jìn)行解碼后的原始數(shù)據(jù)。

需要注意的是,這個(gè)示例代碼中的Huffman樹和待解壓縮的數(shù)據(jù)都是固定的,實(shí)際應(yīng)用中可能需要根據(jù)具體的壓縮數(shù)據(jù)和Huffman樹結(jié)構(gòu)進(jìn)行相應(yīng)的解壓縮處理。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 算法
    +關(guān)注

    關(guān)注

    23

    文章

    4612

    瀏覽量

    92891
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    180

    文章

    7604

    瀏覽量

    136823
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4331

    瀏覽量

    62618
  • Huffman
    +關(guān)注

    關(guān)注

    0

    文章

    4

    瀏覽量

    6356

原文標(biāo)題:Huffman算法壓縮解壓縮(C)

文章出處:【微信號(hào):leezym0317,微信公眾號(hào):FPGA開源工作室】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    【案例分享】經(jīng)典的壓縮算法Huffman算法

    前兩天發(fā)布那個(gè)rsync算法后,想看看數(shù)據(jù)壓縮算法,知道一個(gè)經(jīng)典的壓縮算法Huffman
    發(fā)表于 07-17 04:30

    STM32自定義USB設(shè)備開發(fā)詳細(xì)流程講解

    STM32自定義USB設(shè)備開發(fā)詳細(xì)流程講解及全套資料源碼下載
    發(fā)表于 08-03 09:50

    關(guān)于ADPCM壓縮算法流程介紹

    關(guān)于ADPCM壓縮算法流程介紹
    發(fā)表于 06-03 06:44

    視頻壓縮算法的特點(diǎn)和處理流程是怎樣的?

    在本文中,我們將著重探討視頻壓縮算法的特點(diǎn)和處理流程,我們將對(duì)基本的視頻壓縮算法進(jìn)行解釋,包括靜態(tài)圖像
    發(fā)表于 06-08 06:49

    常用數(shù)據(jù)無(wú)損壓縮算法分析

    在數(shù)據(jù)采集和數(shù)據(jù)傳輸系統(tǒng)中常運(yùn)用數(shù)據(jù)壓縮技術(shù),數(shù)據(jù)壓縮通常可分為無(wú)損壓縮和有損壓縮兩種。結(jié)合常用數(shù)據(jù)無(wú)損壓縮
    發(fā)表于 12-23 10:17 ?0次下載

    多晶硅制備詳細(xì)流程及圖解

    多晶硅制備詳細(xì)流程
    發(fā)表于 01-10 16:18 ?66次下載
    多晶硅制備<b class='flag-5'>詳細(xì)流程</b>及圖解

    基于ADPCM的語(yǔ)音壓縮算法研究

    摘 要 ADPCM算法目前已成為很受用的語(yǔ)音壓縮算法之一。給出PCM概念。討論DPCM,DM,ADM與ADPCM的 壓縮算法原理以及
    發(fā)表于 04-08 11:20 ?84次下載

    基于0閾值的雙位圖壓縮_雙Huffman組合壓縮算法_許海英

    基于0閾值的雙位圖壓縮_雙Huffman組合壓縮算法_許海英
    發(fā)表于 03-19 11:31 ?0次下載

    JPEG圖像壓縮算法流程詳解

    在實(shí)際應(yīng)用中,JPEG圖像編碼算法使用的大多是離散余弦變換、Huffman編碼、順序編碼模式。這樣的方式,被人們稱為JPEG的基本系統(tǒng)。這里介紹的JPEG編碼算法流程,也是針對(duì)基本系
    發(fā)表于 12-01 09:20 ?4.2w次閱讀
    JPEG圖像<b class='flag-5'>壓縮</b><b class='flag-5'>算法</b><b class='flag-5'>流程</b>詳解

    Huffman霍夫曼壓縮編碼算法實(shí)現(xiàn)分析

    哈夫曼編碼Huffman方法于1952年問(wèn)世,迄今為止仍經(jīng)久不衰,廣泛應(yīng)用于各種數(shù)據(jù)壓縮技術(shù)中,且仍不失為熵編碼中的最佳編碼方法,deflate等壓縮算法也是結(jié)合了
    發(fā)表于 12-01 09:56 ?6950次閱讀

    PID程序算法詳細(xì)資料概述免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是PID程序算法詳細(xì)資料概述免費(fèi)下載
    發(fā)表于 07-24 08:00 ?36次下載

    壓縮感知的理論框架和應(yīng)用的系統(tǒng)概述和信號(hào)重構(gòu)算法研究

    本文對(duì)壓縮感知理論的理論框架和應(yīng)用進(jìn)行了系統(tǒng)概述。該理論針對(duì)稀疏信號(hào),在對(duì)信號(hào)進(jìn)行采樣的同時(shí)完成數(shù)據(jù)壓縮,從而大量節(jié)約了計(jì)算資源、存儲(chǔ)資源和傳輸資源。它包括信號(hào)的稀疏變換、觀測(cè)矩陣的設(shè)計(jì)和信號(hào)的重構(gòu)
    發(fā)表于 12-18 17:21 ?8次下載
    <b class='flag-5'>壓縮</b>感知的理論框架和應(yīng)用的系統(tǒng)<b class='flag-5'>概述</b>和信號(hào)重構(gòu)<b class='flag-5'>算法</b>研究

    PE工具安裝的詳細(xì)流程詳細(xì)說(shuō)明

    PE工具安裝的詳細(xì)流程詳細(xì)說(shuō)明
    發(fā)表于 12-10 08:00 ?29次下載

    BOSHIDA DC電源模塊檢測(cè)穩(wěn)定性能詳細(xì)流程

    BOSHIDA DC電源模塊檢測(cè)穩(wěn)定性能詳細(xì)流程 DC電源模塊是電力電子產(chǎn)品中非常常見和重要的設(shè)備。它們被廣泛應(yīng)用于各種公共場(chǎng)所和工業(yè)領(lǐng)域,如通信系統(tǒng)、計(jì)算機(jī)、工業(yè)自動(dòng)化以及醫(yī)療設(shè)備等。為確保電源
    的頭像 發(fā)表于 06-30 11:08 ?614次閱讀
    BOSHIDA DC電源模塊檢測(cè)穩(wěn)定性能<b class='flag-5'>詳細(xì)流程</b>

    自動(dòng)售貨機(jī)MDB協(xié)議中文解析(七)MDB-RS232控制紙幣器的詳細(xì)流程和解析

    自動(dòng)售貨機(jī)MDB協(xié)議中文解析(七)MDB-RS232控制紙幣器的詳細(xì)流程和解析
    的頭像 發(fā)表于 09-09 10:04 ?575次閱讀
    主站蜘蛛池模板: 欧美一级在线观看播放| 国产精品久线观看视频| 大又大粗又爽又黄少妇毛片| 男啪女色黄无遮挡免费视频| 色网址在线| 日韩在线视频一区| 99久久网站| 午夜一级毛片| 清纯漂亮小美女准备啪啪| 亚洲区| 色多多入口| 亚洲免费看片| 中文字幕亚洲一区二区va在线| 四虎永久在线精品免费影视| 国产精品日本亚洲777| 俄罗斯欧美色黄激情| 亚洲伊人久久在| 国产成都一二三四区| 天天操中文字幕| 欧美19禁| 久操色| 成在线人永久免费播放视频| 亚洲bt天堂| 欧美一区二区三区免费| 午夜一级免费视频| 日本视频一区二区| 看日本黄色大片| 国产精品免费看久久久香蕉| 亚洲va中文字幕| 中文在线天堂网www| 黄频网| 女人张开腿给人桶免费视频| 人人操天天射| 亚洲色图图片| www.91在线播放| 日本一区免费在线观看| 久草视频这里只有精品| 色综合啪啪| 欧美地区一二三区| 波多野结衣三个女人蕾丝边| 色拍拍视频|