一.實驗原理
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編譯通過...