實驗三 Huffman編譯碼

2021-07-31 10:05:29 字數 4708 閱讀 3627

一.實驗原理

1.huffman編碼的步驟:

(1)首先將所有字元發生的概率從小到大進行排序;

(2)將最小的兩個概率進行兩兩一合併,之後繼續找最小的兩個概率進行合併包括前面已經合併的和數;

(3)一步步合併直到最終的根處為1就此形成了一棵二叉樹,再進行碼字編寫,從根部開始樹枝處左零右一在,或是左一右零均可以,從根到樹葉的部分形成乙個碼字,依次讀出碼字形成碼表完成最終的編碼。

2.二叉樹的基本結構及其定義:

完成huffman編碼的主要步驟就是二叉樹的建立,二叉樹主要有中間節點和樹葉的區分,對樹葉而言是沒有孩子的,而中間節點則是有孩子的;

(1)哈夫曼節點結構

typedef struct huffman_node_tag //節點資料型別

unsigned char isleaf; //1表示為葉節點,0表示不是葉節點

unsigned long count; //這個位元組在檔案中出現的次數

struct huffman_node_tag *parent; //父節點指標

union

struct

huffman_node;

(2)哈夫曼碼字結構

typedef struct huffman_code_tag //碼字資料型別

unsigned long numbits;// 該碼所用的位元數

unsigned char *bits;  // 指向該碼位元串的指標

}huffman_code;

二.實驗流程

(1)讀入檔案;

(2)第一次掃瞄檔案統計各個位元組出現的概率;

(3)建立huffman樹;

(4)將碼表以及其他必要資訊寫入輸出檔案;

(5)第二次掃瞄檔案,對原始檔進行編碼輸出;

三.主要**分析

主函式:

#include "huffman.h"

#include #include #include #include #include #include "getopt.h"

#pragma comment(lib,"ws2_32.lib")

#ifdef win32

#include extern int getopt(int, char**, char*);

extern char* optarg;

#else

#include #endif

static int memory_encode_file(file *in, file *out);

static int memory_decode_file(file *in, file *out);

static void

version(file *out)

static void

usage(file* out)

int main(int argc, char** argv)//argc:表示命令行引數的個數,argv:命令列引數指標

} /* if an input file is given then open it. */

//給定輸入檔案,開啟

if(file_in) }

/* if an output file is given then create it. */

//建立輸出檔案並開啟

if(file_out) }

//輸出列表

if(file_out_table) }

// if(memory)//memory=1:進行記憶體編譯碼

if(compress) //compress=1:進行檔案編譯碼

huffman_encode_file(in, out,outtable);//

else

huffman_decode_file(in, out);

//關閉檔案

if(in)

fclose(in);

if(out)

fclose(out);

if(outtable)

fclose(outtable);

return 0;

}static int

memory_encode_file(file *in, file *out)

buf = tmp;//否則,buf指向已重新分配的記憶體

//將輸入檔案中長度為inc的資料讀入buf+cur之後的記憶體中

cur += fread(buf + cur, 1, inc, in);//cur的最終值為讀入檔案的大小

} if(!buf)//如果待寫入記憶體為空,返回1

return 1;

/* encode the memory. */

//對輸入記憶體進行編碼

/*cur:表示輸入記憶體長度,即輸入檔案大小,前面讀入檔案確定

第三個形參是二級指標,實參是指標bufout的位址??????*/

if(huffman_encode_memory(buf, cur, &bufout, &bufoutlen))

//記憶體編碼完成,釋放輸入記憶體空間

free(buf);//即使記憶體編碼沒有完成,也要釋放輸入記憶體

/* write the memory to the file. */

//將輸出記憶體中的資料寫入輸出檔案

if(fwrite(bufout, 1, bufoutlen, out) != bufoutlen)

free(bufout);//釋放輸出記憶體

return 0;

}//記憶體解碼,與編碼原理基本一致,呼叫函式

static int memory_decode_file(file *in, file *out)

buf = tmp;

cur += fread(buf + cur, 1, inc, in);

} if(!buf)

return 1;

/* decode the memory. */

if(huffman_decode_memory(buf, cur, &bufout, &bufoutlen))

free(buf);

/* write the memory to the file. */

if(fwrite(bufout, 1, bufoutlen, out) != bufoutlen)

free(bufout);

return 0;

}

getopt.c檔案:

#include #include #include /* declarations to provide consistent linkage */

extern char *optarg;

extern int optind;

extern int opterr;

int opterr = 1, /* if error message should be printed */

optind = 1, /* index into parent argv vector */

optopt, /* character checked for validity */

optreset; /* reset getopt */

char *optarg; /* argument associated with option */

#define badch (int)'?'

#define badarg (int)':'

#define emsg ""

/* * getopt --

* parse argc/argv argument vector.

*/int

getopt(int nargc, char * const *nargv, const char* ostr)

if (place[1] && *++place == '-')

} /* option letter okay? */

if ((optopt = (int)*place++) == (int)':' ||

!(oli =(char *) strchr(ostr, optopt)))

if (*++oli != ':')

else

else /* white space */

optarg = nargv[optind];

place = emsg;

++optind;

} return (optopt); /* dump back option letter */

}

四.實驗結果

五.實驗結果分析
對於已經壓縮過的rar檔案而言,已經沒有過多的冗餘可以壓縮了,***,mp4等可以壓縮的空間也不大,而word文件以及excel則可以較大幅度的壓縮。

Huffman編碼與解碼

近期學習資料結構碰到huffman編碼與解碼問題,自己動手寫了一些,注釋比較全,ok,下面直接貼 include include define telemtype char define wtype int define leafnumber 5 預設權重集合大小 define totalnumbe...

huffman編碼和解碼實現

寫資料結構的實驗確實是蠻麻煩的,下面提供乙個還可以執行的源程式給大家參考,應付實驗老師是綽綽有餘的了 link.h檔案內容 pragma once class link link的實現檔案什麼內容也沒有,所以就不寫啦 huffman.h內容 pragma once include link.h cl...

Huffman樹的編碼解碼

上個學期做的課程設計,關於huffman樹的編碼解碼。要求 輸入huffman樹各個葉結點的字元和權值,建立huffman樹並執行編碼操作 輸入一行僅由01組成的電文字串,根據建立的huffman樹進行解碼操作,程式最後輸出解碼後的結果 huffman.h定義了樹的結點資訊,各種操作。gcc編譯通過...