国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

計算哈夫曼編碼長度

2019-11-09 19:38:40
字體:
供稿:網(wǎng)友
本篇文章向大家介紹一個不用構(gòu)造哈夫曼樹的方法來計算哈夫曼編碼的長度,這對于較大字符集有極大的優(yōu)勢,因為構(gòu)造一個樹要花費相當(dāng)大的空間和時間,本算法的時間復(fù)雜度為O(nlogn),空間復(fù)雜度為O(N);參考文獻<深入搜索引擎>第二章程序處理:高亮顯示#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>using namespace std;#define BUFF_SIZE 4096#define HASH_SIZE 256char buff[BUFF_SIZE];        //緩沖區(qū) int  hash[HASH_SIZE];        //統(tǒng)計每個字符出現(xiàn)的次數(shù)int heap[(HASH_SIZE<<1)+2];int pos[HASH_SIZE+1][3];//內(nèi)部節(jié)點 , 0和1記錄子結(jié)點位置,3節(jié)錄當(dāng)前的深度int tlen[HASH_SIZE+1];       //記錄每個葉子結(jié)點的深度int  fd;                      //文件描述符int sym_num ;           //文件中出現(xiàn)的符號數(shù)量int SUM(0);             //文件中字符總數(shù)//初始化程序void init(const char * pathname){       memset(buff , 0 , sizeof(buff));       memset(hash , 0 , sizeof(hash));       memset(heap , 0 , sizeof(heap));       memset(pos  , 0 , sizeof(pos));       memset(tlen , 0 , sizeof(tlen));       //打開文件       fd = open(pathname , O_RDONLY);       if(fd < 0){              PRintf("init: %s dont exit!/n" , pathname);              exit(1);       }}//統(tǒng)計文件中每個符號出現(xiàn)的次數(shù)void count_symbol(){       lseek(fd , 0 , SEEK_SET);       while(read(fd , buff , BUFF_SIZE)){              SUM += strlen(buff);              for(int i=strlen(buff) - 1;i>=0;i--)                     hash[(unsigned int)(buff[i] & 0xFF)]++;       }       //記錄出現(xiàn)的符號數(shù)量;       for(int i = HASH_SIZE - 1; i >= 0; i--)              if(hash[i])sym_num++;}//建立一個最小堆void build_min_heap(){       for(int i=sym_num;i>0;i--){              int p = i >> 1 , j = i;              while(p >= 1){                     if(heap[heap[p]] > heap[heap[j]])                            std::swap(heap[j] , heap[p]);                     j = p; p >>= 1;              }       }}//每次取出最小數(shù)之后重新調(diào)整堆,//h 指推中元素的個數(shù)void heap_adjust(int h){       int t = 1 , p , q , l;       while(t<h){              p = t<<1; q = p + 1; l = t;              if(p <= h && heap[heap[p]] < heap[heap[t]])l = p;              if(q <= h && heap[heap[q]] < heap[heap[l]])l = q;              if(l == t)break;              std::swap(heap[l] , heap[t]);              t = l;       }}//計算每個字符編碼的長度void huff_length(){       int i , j , p , h , m1 , m2;       for(i=1 , p=0;i<=sym_num;i++){              while(!hash[p])       p++;              heap[sym_num + i] = hash[p];              heap[i] = sym_num + i;              p++;       }       h = sym_num;       //對1到n建立最小堆       build_min_heap();       while(h>1){              //取出最小數(shù)              m1 = heap[heap[1]];              pos[h][0] = heap[1];              heap[1] = heap[h];              h--;              heap_adjust(h);              //取出次小數(shù)              m2 = heap[heap[1]];              pos[h+1][1] = heap[1];              //最后數(shù)和次小數(shù)之和放在堆的最后一個位置              heap[h+1] = m1 + m2;              //重新指向最新合并的結(jié)點              heap[1] = h+1;              heap_adjust(h);       }       //統(tǒng)計編碼長度 , 線性時間統(tǒng)計       int ts = sym_num << 1;       for(int i=2;i<=sym_num;i++){              if(pos[i][0] <= sym_num) pos[pos[i][0]][2] = pos[i][2] + 1;              else tlen[pos[i][0] - sym_num] = pos[i][2] + 1;              if(pos[i][1] <= sym_num) pos[pos[i][1]][2] = pos[i][2] + 1;              else tlen[pos[i][1] - sym_num] = pos[i][2] + 1;       }}int main(){       init("data.dat");       count_symbol();       huff_length();       unsigned int sum = 0;       for(int i=1;i<=sym_num;i++)              sum += tlen[i] * heap[sym_num + i];       cout<<SUM <<"/t/t"<<sum<<"/t/t"<<sum*1.0/SUM<<endl;       return 0;}
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 北海市| 文化| 沙洋县| 南投市| 五指山市| 会同县| 鹰潭市| 岳普湖县| 东兰县| 贵溪市| 巢湖市| 虞城县| 南平市| 鲁山县| 浦县| 乌审旗| 横峰县| 张北县| 嘉鱼县| 虎林市| 永胜县| 东阳市| 潼关县| 瑞金市| 宾阳县| 陈巴尔虎旗| 仪征市| 平乐县| 方城县| 南丹县| 政和县| 阳东县| 建德市| 保定市| 大足县| 双辽市| 阳山县| 松潘县| 福海县| 特克斯县| 泾川县|