A. Huffman編碼不適合圖像壓縮么,為什麼。有相關的資料么。能給我看看不QQ504278770
下面是我從網上搜索到的資料,希望對你有幫助。
1.哈夫曼圖像壓縮演算法引言
隨著網路與多媒體技術的興起,人們需要存儲和傳輸的數據越來越多,數據量越來越大,以前帶寬有限的傳輸網路和容量有限的存儲介質難以滿足用戶的需求。
特別是聲音、圖像和視頻等媒體在人們的日常生活和工作中的地位日益突出,這個問題越發顯得嚴重和迫切。如今,數據壓縮技術早已是多媒體領域中的關鍵技術之一。
Huffman(哈夫曼)演算法在上世紀五十年代初提出來了,它是一種無損壓縮方法,在壓縮過程中不會丟失信息熵,而且可以證明Huffman演算法在無損壓縮演算法中是最優的。Huffman原理簡單,實現起來也不困難,在現在的主流壓縮軟體得到了廣泛的應用。對應用程序、重要資料等絕對不允許信息丟失的壓縮場合,Huffman演算法是非常好的選擇。
2.哈夫曼圖像壓縮演算法原理
Huffman編碼是1952年由Huffman提出的對統計獨立信源能達到最小平均碼長的編碼方法。這一年,他發表了著名論文「A Method for the Construction of Minimum Rendancy Codes」,即最短冗餘碼的構造方法.之後,Huffman編碼及其一些改進方法一直是數據壓縮領域的研究熱點之一。
Huffman碼是一種變長碼,其基本思想是:先統計圖像(已經數字化)中各灰度出現的概率,出現概率較大的賦以較短的碼字,而出現概率較小的則賦以較長的碼字。我們可以用下面的框圖來表示Huffman編碼的過程:
在整個編碼過程中,統計圖像各灰度級出現的概率和編碼這兩步都很簡單,關鍵的是Huffman樹的構造。不但編碼的時候需要用到這顆樹,解碼的時候也必須有這顆樹才能完成解碼工作,因此,Huffman樹還得完整的傳輸到解碼端。
Huffman樹的構造可以按照下面圖2的流程圖來完成。首先對統計出來的概率從小到大進行排序,然後將最小的兩個概率相加;到這兒的時候,先把已經加過的兩個概率作為樹的兩個節點,並把他們從概率隊列中刪除;然後把相加所得的新概率加入到隊列中,對這個新隊列進行排序。
如此反復,直到最後兩個概率相加為1的時候停止。這樣,Huffman樹就建立起來了。
3. 哈夫曼圖像壓縮演算法軟體實現
這兒,我們以Turbo C為例來說明軟體實現Huffman圖像壓縮演算法的一些關鍵技術。
為了敘述方便,我們不妨假設處理的圖像的灰度級變化范圍從0到255,即具有256個灰度級。我們先來統計輸入圖像的概率,實際上是要統計各個灰度級在整幅圖像中出現的次數。為此,我們先定義一個具有256個元素的數組。
然後對輸入圖像信號進行掃描,每出現一個灰度,就把它存入實現定義好的一個數組中的相應元素中(讓這個元素的值自增1)。最後,通過讀取數組中各元素的值就可以求出各個灰度出現的頻數。
接下來就該構造Huffman樹了。為了構造Huffman樹,我們要用到C語言中鏈表的概念。我們必須用一個結構體來表示Huffman樹的節點。對於每個節點而言我們需要這樣幾個信息:本節點的權重(就是灰度的頻數)、指向父節點的指針和分別指向左右子葉節點的指針。於是,我們可以定義這樣一個結構體:
Struct Node{
Floatweight;
Node * father;
Node * left;
Node * right;}Huffman_Node
我們需要先確定權最低的兩個自由結點,這將是最初的left和right節點。然後建立這兩個結點的父結點,並讓它的權等於這兩個結點的權之和。
接著將這個父結點增加到自由結點的序列中,而兩個子結點則從序列中去掉。重復前面的步驟直到只剩下一個自由結點,這個自由結點就是Huffman樹的根。
Huffman編碼樹作為一個二叉樹從葉結點逐步向上建立。Huffman樹建立好以後,為了把權、概率等數值轉化碼字,我們還得對整個Huffman樹進行掃描。請注意,在建立Huffman樹的時候,我們是從樹葉開始的,而在對Huffman樹分配碼字的時候卻剛好相反,是從樹根開始,沿著各個樹枝的走向「順藤摸瓜」似的對各個系數進行編碼。
對於一個節點的兩個子節點(left和right),其中一個節點對應的位為0,而另一個結點則人為地設置成為l。解碼的時候也是完全相同的一顆Huffman樹完成的。下面的循環是實現壓縮的關鍵語句之一[ 1 ]。
for (i = length-1; i >= 0; ――i) {
if ((current_code >> i) & 1)
thebyte |= (char) (1 << curbit);
if (--curbit < 0) {
putc (thebyte, ofile);
thebyte = 0;
curbyte++;
curbit = 7;
}
}
注意:這幾行代碼執行了數據壓縮的功能,但是還沒有生成編碼和解碼所需要的代碼表。
4.哈夫曼圖像壓縮演算法性能評價
我們主要從三方面[ 2 ]來評價Huffman的性能:
(1)壓縮比的大小;
(2)恢復效果的好壞,也就是能否盡可能的恢復原始數據;
(3)演算法的簡單易用性以及編、解碼的速度。
首先分析一下對壓縮比的影響因素(不同的著作中對壓縮比的定義不盡相同,這兒我們採用如下定義:壓縮比等於壓縮之前的以比特計算的數據量比上壓縮之後的數據量)。對於Huffman編碼來說,我們因為要用額外的位保存和傳輸Huffman樹而「浪費」掉一些存儲位,也就是說,為了編、解碼的方便,我們把本已減少的數據量又增加了一些。
如果文件比較大的話,這一點多餘的數據根本算不了什麼,所佔比例很小。但是,如果壓縮的文件本來就很小的話,那麼這筆數據就很可觀了。一般來說,經典的Huffman演算法的壓縮比不是很高,這是無損壓縮的「通病」。
第二點就不用說了,由於它是無損壓縮,能夠完全恢復壓縮之前圖像的本來面貌。
最後,讓我們來分析一下Huffman壓縮方法的速度問題。大家在第三節中已經看到了,在壓縮的過程中,我們進行了兩次掃描,第一次是為了統計各個灰度出現的頻數而掃描整幅圖像,第二次則是為了分配碼字而掃描整個Huffman樹。
這樣一來,對較大的文件進行編碼時,頻繁的磁碟讀寫訪問必然會降低數據編碼的速度,如果用於網路的話,還會因此帶來一些延時,不利於實時壓縮和傳輸。另外,Huffman演算法的編碼和解碼的速度是不對稱的,解碼快於編碼,因為解碼不需要生成Huffman樹的環節。
5.圖像壓縮演算法結束語
Huffman演算法目前已經得到了廣泛的應用,軟體和硬體都已經實現。基於Huffman經典演算法的缺陷,不少人提出了一些自適應演算法。前面的演算法中,Huffman樹是整個圖像全部輸入掃描完成後構造出來的,而自適應演算法(或稱動態演算法)則不必等到全部圖像輸入完成才開始樹的構造,並且可以根據後面輸入的數據動態的對Huffman樹進行調整。實際上,實用的Huffman樹都是經過某種優化後的動態演算法。
網路資源
B. 有人能給我一份哈夫曼編碼的壓縮和解壓么
把要壓縮或要解壓的文件拖拽到窗口中即可。另存為編輯框是壓縮或解壓的輸出路徑。對於壓縮來說,另存為路徑是目標文件的路徑加上一個.shc擴展名。對於解壓來說,會去掉最後一個擴展名。
壓縮的核心其實就是用了哈夫曼編碼原理。我封裝了一個哈夫曼編碼類,內部使用了一個哈夫曼樹類。
要對一個文件進行壓縮,執行如下步驟:
1.建立編碼方案。第一遍掃描文件,統計這個文件中各種不同的位元組出現的次數(256種),以這個次數作為權值,建立對應的哈夫曼樹。然後取得每個不同位元組對應的01編碼序列。
C. 對圖像進行霍夫曼編碼壓縮後如何輸出壓縮後圖像
壓縮後的圖像就是哈夫曼編碼後的01比特流
D. 如何用哈夫曼編碼實現英文文本的壓縮和解壓縮
哈夫曼壓縮是個無損的壓縮演算法,一般用來壓縮文本和程序文件。哈夫曼壓縮屬於可變代碼長度演算法一族。意思是個體符號(例如,文本文件中的字元)用一個特定長度的位序列替代。因此,在文件中出現頻率高的符號,使用短的位序列,而那些很少出現的符號,則用較長的位序列。有人用C函數寫了這個編碼,見下面鏈接
http://ke..com/view/189694.htm
E. 基於哈夫曼編碼的圖像壓縮編碼程序設計 計算出壓縮比對編碼後的數據進行解壓,並顯示解壓後的圖像;
我空間有篇大學時候寫的Huffman演算法,C++的,可以編譯運行的,不過是控制台的
Huffman本身不適合壓縮圖片,視頻之類,只有對文本壓縮效果比較好。
F. 哈夫曼編碼進行圖像壓縮
% 演示圖象的哈夫曼編解碼過程
% chenyong 2009.04.20
clear all;
close all;
clc;
Dimens = 256; % 矩陣維數,假設矩陣為方陣即256*256
src_size = Dimens^2; % 矩陣元素的個數
gray_level = 9; % 灰度級
src = randn(Dimens); %產生模擬圖像矩陣,滿足正態分布,零均值,方差為1
%src = randint(Dimens,Dimens,gray_level); % 產生隨機圖像矩陣,灰度值為0~63,滿足均勻分布
src_one = reshape(src,1,src_size);
src_max = max(src_one);
src_min = min(src_one);
quan = linspace(src_min,src_max,gray_level); % 產生均勻量化區間
src_d = []; % 數字矩陣
for row = 1:Dimens % 逐點量化
for vol = 1:Dimens
diff = abs(src(row,vol)-quan);
[min_diff,min_index] = min(diff);
quan_gray = min_index -1;
src_d(row,vol) = quan_gray;
end
end
%將數字圖像矩陣還原成模擬矩陣
src_a = [];
quan_space = quan(2)-quan(1);
for row = 1:Dimens
for vol = 1:Dimens
src_a(row,vol) = src_d(row,vol) * quan_space + src_min;
end
end
% prob數組保存圖像中各灰度出現的概率
prob = [];
for src_value=0:(gray_level-1)
index = find(src_d==src_value);
i = src_value + 1;
prob(i) = length(index)/src_size;
end
% 畫出直方圖
% stem(0:gray_level-1,prob);
% xlabel('灰度值');
% ylabel('概率');
% title('灰度直方圖');
% huffman編碼
p = prob;
n=length(p);
q=p;
m=zeros(n-1,n);
for i=1:n-1
[q,l]=sort(q);
m(i,:)=[l(1:n-i+1),zeros(1,i-1)];
q=[q(1)+q(2),q(3:n),1];
end
bre=zeros(n-1,n);
bre(n-1,1)=0+j; %虛部表示當前的二進制數的位數,以下類似
bre(n-1,2)=1+j;
for time=1:n-2
loc_1 = find(real(m(n-time,:))==1);
prebit = bre(n-time,loc_1);
bre(n-time-1,1) = (real(prebit)*2 + 0) + j*(imag(prebit)+1);
bre(n-time-1,2) = (real(prebit)*2 + 1) + j*(imag(prebit)+1);
loc_not1 = find(real(m(n-time,:))>1);
bre(n-time-1,3:3+time-1) = bre(n-time,loc_not1);
end
[m1,index] = sort(m(1,:));
code = bre(1,index);
code_data = real(code);
code_bits = imag(code);
disp(['gray level',' ', 'huffman code']);
for i = 1:length(code)
disp([num2str(i-1),' ' ,num2str(dec2bin(code_data(i)))]);
disp([num2str(i-1),' ' ,num2str(dec2bin(code_data(i),code_bits(i)))]);
end
code_binary = dec2bin(code_data);
%逐點編碼
out = [];
for row = 1:Dimens
for vol = 1:Dimens
now_gray = src_d(row,vol);
now_code = code_binary(now_gray+1,:);
now_bits = code_bits(now_gray+1);
now_code = now_code(end-now_bits+1:end);
out = [out, now_code];
end
end
%計算壓縮比
real_bitnum = length(out);
bitnum_no_huffman = src_size*nextpow2(gray_level);
comp_ratio =bitnum_no_huffman/real_bitnum;
Lavg = real_bitnum/src_size;
Hshannon = (-1)*prob*(log2(prob))';
disp(['Lavg = ',num2str(Lavg)]);
disp(['normal bit num = ',num2str(nextpow2(gray_level))]);
disp(['comp_ratio = ',num2str(comp_ratio)]);
disp(['Hshannon = ',num2str(Hshannon)]);
G. 有關哈夫曼編碼壓縮與解壓縮的問題.
壓縮代碼非常簡單,首先用ASCII值初始化511個哈夫曼節點:
CHuffmanNode nodes[511];
for(int nCount = 0; nCount < 256; nCount++)
nodes[nCount].byAscii = nCount;
然後,計算在輸入緩沖區數據中,每個ASCII碼出現的頻率:
for(nCount = 0; nCount < nSrcLen; nCount++)
nodes[pSrc[nCount]].nFrequency++;
然後,根據頻率進行排序:
qsort(nodes, 256, sizeof(CHuffmanNode), frequencyCompare);
現在,構造哈夫曼樹,獲取每個ASCII碼對應的位序列:
int nNodeCount = GetHuffmanTree(nodes);
構造哈夫曼樹非常簡單,將所有的節點放到一個隊列中,用一個節點替換兩個頻率最低的節點,新節點的頻率就是這兩個節點的頻率之和。這樣,新節點就是兩個被替換節點的父節點了。如此循環,直到隊列中只剩一個節點(樹根)。
// parent node
pNode = &nodes[nParentNode++];
// pop first child
pNode->pLeft = PopNode(pNodes, nBackNode--, false);
// pop second child
pNode->pRight = PopNode(pNodes, nBackNode--, true);
// adjust parent of the two poped nodes
pNode->pLeft->pParent = pNode->pRight->pParent = pNode;
// adjust parent frequency
pNode->nFrequency = pNode->pLeft->nFrequency + pNode->pRight->nFrequency;
這里我用了一個好的訣竅來避免使用任何隊列組件。我先前就直到ASCII碼只有256個,但我分配了511個(CHuffmanNode nodes[511]),前255個記錄ASCII碼,而用後255個記錄哈夫曼樹中的父節點。並且在構造樹的時候只使用一個指針數組(ChuffmanNode *pNodes[256])來指向這些節點。同樣使用兩個變數來操作隊列索引(int nParentNode = nNodeCount;nBackNode = nNodeCount –1)。
接著,壓縮的最後一步是將每個ASCII編碼寫入輸出緩沖區中:
int nDesIndex = 0;
// loop to write codes
for(nCount = 0; nCount < nSrcLen; nCount++)
{
*(DWORD*)(pDesPtr+(nDesIndex>>3)) |=
nodes[pSrc[nCount]].dwCode << (nDesIndex&7);
nDesIndex += nodes[pSrc[nCount]].nCodeLength;
}
(nDesIndex>>3): >>3 以8位為界限右移後到達右邊位元組的前面
(nDesIndex&7): &7 得到最高位.
注意:在壓縮緩沖區中,我們必須保存哈夫曼樹的節點以及位序列,這樣我們才能在解壓縮時重新構造哈夫曼樹(只需保存ASCII值和對應的位序列)。
解壓縮
解壓縮比構造哈夫曼樹要簡單的多,將輸入緩沖區中的每個編碼用對應的ASCII碼逐個替換就可以了。只要記住,這里的輸入緩沖區是一個包含每個ASCII值的編碼的位流。因此,為了用ASCII值替換編碼,我們必須用位流搜索哈夫曼樹,直到發現一個葉節點,然後將它的ASCII值添加到輸出緩沖區中:
int nDesIndex = 0;
DWORD nCode;
while(nDesIndex < nDesLen)
{
nCode = (*(DWORD*)(pSrc+(nSrcIndex>>3)))>>(nSrcIndex&7);
pNode = pRoot;
while(pNode->pLeft)
{
pNode = (nCode&1) ? pNode->pRight : pNode->pLeft;
nCode >>= 1;
nSrcIndex++;
}
pDes[nDesIndex++] = pNode->byAscii;
}
過程
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#include<math.h>
#define M 10
typedef struct Fano_Node
{
char ch;
float weight;
}FanoNode[M];
typedef struct node
{
int start;
int end;
struct node *next;
}LinkQueueNode;
typedef struct
{
LinkQueueNode *front;
LinkQueueNode *rear;
}LinkQueue;
void EnterQueue(LinkQueue *q,int s,int e)
{
LinkQueueNode *NewNode;
NewNode=(LinkQueueNode *)malloc(sizeof(LinkQueueNode));
if(NewNode!=NULL)
{
NewNode->start=s;
NewNode->end=e;
NewNode->next=NULL;
q->rear->next=NewNode;
q->rear=NewNode;
}
else printf("Error!");
}
//***按權分組***//
void Divide(FanoNode f,int s,int *m,int e)
{
int i;
float sum,sum1;
sum=0;
for(i=s;i<=e;i++)
sum+=f.weight;
*m=s;
sum1=0;
for(i=s;i<e;i++)
{
sum1+=f.weight;
*m=fabs(sum-2*sum1)>fabs(sum-2*sum1-2*f.weight)?(i+1):*m;
if(*m==i)
break;
}
}
main()
{
int i,j,n,max,m,h[M];
int sta,mid,end;
float w;
char c,fc[M][M];
FanoNode FN;
LinkQueueNode *p;
LinkQueue *Q;
//***初始化隊Q***//
Q->front=(LinkQueueNode *)malloc(sizeof(LinkQueueNode));
Q->rear=Q->front;
Q->front->next=NULL;
printf("\t***FanoCoding***\n");
printf("Please input the number of node:"); /*輸入信息*/
scanf("%d",&n);
i=1;
while(i<=n)
{
printf("%d weight and node:",i);
scanf("%f %c",&FN.weight,&FN.ch);
for(j=1;j<i;j++)
{
if(FN.ch==FN[j].ch)
{
printf("Same node!!!\n");
break;
}
}
if(i==j)
i++;
}
for(i=1;i<=n;i++) /*排序*/
{
max=i+1;
for(j=max;j<=n;j++)
max=FN[max].weight<FN[j].weight?j:max;
if(FN.weight<FN[max].weight)
{
w=FN.weight;
FN.weight=FN[max].weight;
FN[max].weight=w;
c=FN.ch;
FN.ch=FN[max].ch;
FN[max].ch=c;
}
}
for(i=1;i<=n;i++) /*初始化h*/
h=0;
EnterQueue(Q,1,n); /*1和n進隊*/
while(Q->front->next!=NULL)
{
p=Q->front->next; /*出隊*/
Q->front->next=p->next;
if(p==Q->rear)
Q->rear=Q->front;
sta=p->start;
end=p->end;
free(p);
Divide(FN,sta,&m,end); /*按權分組*/
for(i=sta;i<=m;i++)
{
fc[h]='0';
h++;
}
if(sta!=m)
EnterQueue(Q,sta,m);
else
fc[sta][h[sta]]='\0';
for(i=m+1;i<=end;i++)
{
fc[h]='1';
h++;
}
if(m==sta&&(m+1)==end) //如果分組後首元素的下標與中間元素的相等,
{ //並且和最後元素的下標相差為1,則編碼碼字字元串結束
fc[m][h[m]]='\0';
fc[end][h[end]]='\0';
}
else
EnterQueue(Q,m+1,end);
}
for(i=1;i<=n;i++) /*列印編碼信息*/
{
printf("%c:",FN.ch);
printf("%s\n",fc);
}
system("pause");
}
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>
#define N 100
#define M 2*N-1
typedef char * HuffmanCode[2*M];
typedef struct
{
char weight;
int parent;
int LChild;
int RChild;
}HTNode,Huffman[M+1];
typedef struct Node
{
int weight; /*葉子結點的權值*/
char c; /*葉子結點*/
int num; /*葉子結點的二進制碼的長度*/
}WNode,WeightNode[N];
/***產生葉子結點的字元和權值***/
void CreateWeight(char ch[],int *s,WeightNode *CW,int *p)
{
int i,j,k;
int tag;
*p=0;
for(i=0;ch!='\0';i++)
{
tag=1;
for(j=0;j<i;j++)
if(ch[j]==ch)
{
tag=0;
break;
}
if(tag)
{
(*CW)[++*p].c=ch;
(*CW)[*p].weight=1;
for(k=i+1;ch[k]!='\0';k++)
if(ch==ch[k])
(*CW)[*p].weight++;
}
}
*s=i;
}
/********創建HuffmanTree********/
void CreateHuffmanTree(Huffman *ht,WeightNode w,int n)
{
int i,j;
int s1,s2;
for(i=1;i<=n;i++)
{
(*ht).weight =w.weight;
(*ht).parent=0;
(*ht).LChild=0;
(*ht).RChild=0;
}
for(i=n+1;i<=2*n-1;i++)
{
(*ht).weight=0;
(*ht).parent=0;
(*ht).LChild=0;
(*ht).parent=0;
}
for(i=n+1;i<=2*n-1;i++)
{
for(j=1;j<=i-1;j++)
if(!(*ht)[j].parent)
break;
s1=j; /*找到第一個雙親不為零的結點*/
for(;j<=i-1;j++)
if(!(*ht)[j].parent)
s1=(*ht)[s1].weight>(*ht)[j].weight?j:s1;
(*ht)[s1].parent=i;
(*ht).LChild=s1;
for(j=1;j<=i-1;j++)
if(!(*ht)[j].parent)
break;
s2=j; /*找到第一個雙親不為零的結點*/
for(;j<=i-1;j++)
if(!(*ht)[j].parent)
s2=(*ht)[s2].weight>(*ht)[j].weight?j:s2;
(*ht)[s2].parent=i;
(*ht).RChild=s2;
(*ht).weight=(*ht)[s1].weight+(*ht)[s2].weight;
}
}
/***********葉子結點的編碼***********/
void CrtHuffmanNodeCode(Huffman ht,char ch[],HuffmanCode *h,WeightNode *weight,int m,int n)
{
int i,j,k,c,p,start;
char *cd;
cd=(char *)malloc(n*sizeof(char));
cd[n-1]='\0';
for(i=1;i<=n;i++)
{
start=n-1;
c=i;
p=ht.parent;
while(p)
{
start--;
if(ht[p].LChild==c)
cd[start]='0';
else
cd[start]='1';
c=p;
p=ht[p].parent;
}
(*weight).num=n-start;
(*h)=(char *)malloc((n-start)*sizeof(char));
p=-1;
strcpy((*h),&cd[start]);
}
system("pause");
}
/*********所有字元的編碼*********/
void CrtHuffmanCode(char ch[],HuffmanCode h,HuffmanCode *hc,WeightNode weight,int n,int m)
{
int i,j,k;
for(i=0;i<m;i++)
{
for(k=1;k<=n;k++) /*從(*weight)[k].c中查找與ch相等的下標K*/
if(ch==weight[k].c)
break;
(*hc)=(char *)malloc((weight[k].num+1)*sizeof(char));
for(j=0;j<=weight[k].num;j++)
(*hc)[j]=h[k][j];
}
}
/*****解碼*****/
void TrsHuffmanTree(Huffman ht,WeightNode w,HuffmanCode hc,int n,int m)
{
int i=0,j,p;
printf("***StringInformation***\n");
while(i<m)
{
p=2*n-1;
for(j=0;hc[j]!='\0';j++)
{
if(hc[j]=='0')
p=ht[p].LChild;
else
p=ht[p].RChild;
}
printf("%c",w[p].c); /*列印原信息*/
i++;
}
}
main()
{
int i,n,m,s1,s2,j; /*n為葉子結點的個數*/
char ch[N],w[N]; /*ch[N]存放輸入的字元串*/
Huffman ht; /*二叉數 */
HuffmanCode h,hc; /* h存放葉子結點的編碼,hc 存放所有結點的編碼*/
WeightNode weight; /*存放葉子結點的信息*/
printf("\t***HuffmanCoding***\n");
printf("please input information :");
gets(ch); /*輸入字元串*/
CreateWeight(ch,&m,&weight,&n); /*產生葉子結點信息,m為字元串ch[]的長度*/
printf("***WeightInformation***\n Node "); /*輸出葉子結點的字元與權值*/
for(i=1;i<=n;i++)
printf("%c ",weight.c);
printf("\nWeight ");
for(i=1;i<=n;i++)
printf("%d ",weight.weight);
CreateHuffmanTree(&ht,weight,n); /*產生Huffman樹*/
printf("\n***HuffamnTreeInformation***\n");
for(i=1;i<=2*n-1;i++) /*列印Huffman樹的信息*/
printf("\t%d %d %d %d\n",i,ht.weight,ht.parent,ht.LChild,ht.RChild);
CrtHuffmanNodeCode(ht,ch,&h,&weight,m,n); /*葉子結點的編碼*/
printf(" ***NodeCode***\n"); /*列印葉子結點的編碼*/
for(i=1;i<=n;i++)
{
printf("\t%c:",weight.c);
printf("%s\n",h);
}
CrtHuffmanCode(ch,h,&hc,weight,n,m); /*所有字元的編碼*/
printf("***StringCode***\n"); /*列印字元串的編碼*/
for(i=0;i<m;i++)
printf("%s",hc);
system("pause");
TrsHuffmanTree(ht,weight,hc,n,m); /*解碼*/
system("pause");
}
H. 哈夫曼編碼法的壓縮和解壓縮怎麼實現
建立一棵赫夫曼樹,設每個父節點的左子節點為1,右子節點為0,然後由根節點到所要編碼的字元的葉節點的路徑確定字元的編碼。比如要編碼a,假設a在第三層,則由根節點到a的路徑為:根節點——右子節點(0)——左子節點(1)。那麼a的編碼就為01。就這樣把所有字元進行編碼,建立一個赫夫曼編碼表。利用這個編碼表把字元串編碼就是壓縮了,解壓縮就是把參照赫夫曼編碼表把編碼轉為字元串。
I. 跪求哈夫曼編碼壓縮與其它壓縮演算法的比較(復雜性和壓縮效果)
(1)所形成的Huffman編碼的碼字是不是唯一的,但是可以被指定為唯一的編碼效率為「1」大,小的是「0」時,兩個最小概率符號賦值。反之也可以。如果兩個符號的發生的概率是相等的,排列無論前面是可能的,所以霍夫曼碼字的結構不是唯一的,對於相同的信息源,不管如何在上述的順序安排的,它的平均碼字長度是不改變,因此,編碼效率是獨一無二的。
(2)只有當不均勻時,每個符號的信息源的發生的概率,霍夫曼編碼的效果是唯一明顯的。
(3)霍夫曼編碼必須是精確的原始文件中的各符號的發生頻率的統計數據,並且如果沒有準確的統計數據,壓縮將低於預期。 Huffman編碼通常必須經過兩道,第一遍統計的第二次產生編碼,編碼速度是比較慢的。電路的復雜性的另一種實現的各種長度的編碼,解碼處理是相對復雜的,因此,解壓縮處理是相對緩慢。
(4)Huffman編碼只能使用整數來表示一個符號,而不是使用小數,這在很大程度上限制了壓縮效果。
(5)霍夫曼是所有的位,如果改變其中一個可以使數據看起來完全不同
J. 如何用哈夫曼編碼製作壓縮解壓縮軟體
去問小翠啊, 望採納,記得給分