回 帖 发 新 帖 刷新版面

主题:哈夫曼编码问题

#include<string.h> 
#include<stdlib.h> 
#include<stdio.h> 

int m,s1,s2; 

typedef struct { 
unsigned int weight; 
unsigned int parent,lchild,rchild; 
}HTNode,*HuffmanTree; //动态分配数组存储哈夫曼树 
typedef char *HuffmanCode; //动态分配数组存储哈夫曼编码表 

void Select(HuffmanTree HT,int n) { 
int i,j; 
for(i = 1;i <= n;i++) 
if(!HT[i].parent){s1 = i;break;} 
for(j = i+1;j <= n;j++) 
if(!HT[j].parent){s2 = j;break;} 
for(i = 1;i <= n;i++) 
if((HT[s1].weight>HT[i].weight)&&(!HT[i].parent)&&(s2!=i))s1=i; 
for(j = 1;j <= n;j++) 
if((HT[s2].weight>HT[j].weight)&&(!HT[j].parent)&&(s1!=j))s2=j; 


void HuffmanCoding(HuffmanTree HT, HuffmanCode HC[], int *w, int n) {  
// w存放n个字符的权值(均>0),构造哈夫曼树HT, 
// 并求出n个字符的哈夫曼编码HC 
int i, j; 
char *cd; 
int p; 
int cdlen; 

if (n<=1) return; 
m = 2 * n - 1; 
HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode)); // 0号单元未用 
for (i=1; i<=n; i++) { //初始化 
HT[i].weight=w[i-1]; 
HT[i].parent=0; 
HT[i].lchild=0; 
HT[i].rchild=0; 

for (i=n+1; i<=m; i++) { //初始化 
HT[i].weight=0; 
HT[i].parent=0; 
HT[i].lchild=0; 
HT[i].rchild=0; 

puts("\n哈夫曼树的构造过程如下所示:"); 
printf("HT初态:\n 结点 weight parent lchild rchild"); 
for (i=1; i<=m; i++) 
printf("\n%4d%8d%8d%8d%8d",i,HT[i].weight, 
HT[i].parent,HT[i].lchild, HT[i].rchild); 
printf(" 按任意键,继续 ..."); 
getchar(); 
for (i=n+1; i<=m; i++) { // 建哈夫曼树 
// 在HT[1..i-1]中选择parent为0且weight最小的两个结点, 
// 其序号分别为s1和s2。 
Select(HT, i-1); 
HT[s1].parent = i; HT[s2].parent = i; 
HT[i].lchild = s1; HT[i].rchild = s2; 
HT[i].weight = HT[s1].weight + HT[s2].weight; 
printf("\nselect: s1=%d s2=%d\n", s1, s2); 
printf(" 结点 weight parent lchild rchild"); 
for (j=1; j<=i; j++) 
printf("\n%4d%8d%8d%8d%8d",j,HT[j].weight, 
HT[j].parent,HT[j].lchild, HT[j].rchild); 
printf(" 按任意键,继续 ..."); 
getchar(); 


//------无栈非递归遍历哈夫曼树,求哈夫曼编码 
cd = (char *)malloc(n*sizeof(char)); // 分配求编码的工作空间 
p = m; cdlen = 0; 
for (i=1; i<=m; ++i) // 遍历哈夫曼树时用作结点状态标志 
HT[i].weight = 0; 
while (p) { 
if (HT[p].weight==0) { // 向左 
HT[p].weight = 1; 
if (HT[p].lchild != 0) { p = HT[p].lchild; cd[cdlen++] ='0'; } 
else if (HT[p].rchild == 0) { // 登记叶子结点的字符的编码 
HC[p] = (char *)malloc((cdlen+1) * sizeof(char)); 
cd[cdlen] ='\0'; strcpy(HC[p], cd); // 复制编码(串) 

} else if (HT[p].weight==1) { // 向右 
HT[p].weight = 2; 
if (HT[p].rchild != 0) { p = HT[p].rchild; cd[cdlen++] ='1'; } 
} else { // HT[p].weight==2,退回退到父结点,编码长度减1 
HT[p].weight = 0; p = HT[p].parent; --cdlen; 


} // HuffmanCoding 
void main() { 
//void HuffmanCoding(HT,HC,w,n);
HuffmanTree HT;
HuffmanCode *HC;
int *w,n,i; 
puts("输入结点数:"); 
scanf("%d",&n); 
HC = (HuffmanCode *)malloc(n*sizeof(HuffmanCode)); 
w = (int *)malloc(n*sizeof(int)); 
printf("输入%d个结点的权值\n",n); 
for(i = 0;i < n;i++) 
scanf("%d",&w[i]); 
HuffmanCoding(HT,HC,w,n); 
puts("\n各结点的哈夫曼编码:"); 
for(i = 1;i <= n;i++) 
printf("%2d(%4d):%s\n",i,w[i-1],HC[i]); 
getchar(); 
}
这个程序是干什么用的

回复列表 (共3个回复)

沙发

注释里不是说的很明白了么……构造哈夫曼树,然后按指定方法求哈夫曼编码

板凳

哦 谢谢 搞懂了  那这个呢 不理解 运行的 每部分代表什么啊
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class node{
      public:
             char data;
             float weight;
};
class huffnode :public node
{
public:
 string code;
 int lchild,rchild,parent;
 int flag;  
};
void select(vector<huffnode> s,int &s1,int &s2){
     s[0].weight = 1; 
  s1 = s2 = 0;
  for(int i = 0; i < s.size(); i++)
  if (s[i].parent == -1)
  {
   if (s[i].weight < s[s1].weight)
    { s2 = s1; s1 = i;}
   else if (s[i].weight < s[s2].weight)
    { s2 = i; }
  }
}
void code(vector<node> weights)
{
 vector<huffnode> h;
 vector<node>::iterator pit_i = weights.begin();
 int nozero_num = 0;
 huffnode m;
 m.weight = 1;
 h.push_back(m);
 while(pit_i != weights.end()){
                if((*pit_i).weight != 0){
                            huffnode n;
                            n.data = (*pit_i).data;
                            n.weight = (*pit_i).weight;
                            n.lchild = n.rchild = n.parent = -1; 
                            h.push_back(n); 
                            nozero_num++;
                }
                pit_i++;
    }
 int s1,s2;
 int j = nozero_num;
 cout<<j<<endl;
    do
 {
  select(h,s1, s2);
  huffnode hn;
  hn.weight = h[s1].weight + h[s2].weight;
  hn.lchild = s1;
  hn.rchild = s2;
  h.push_back(hn);
  h[s1].parent = h[s2].parent = 1;
  j--;
 }while(j != 1);
    int p = h.size()-1;
 while(p != 0)
 {
            if(h[p].lchild != -1){
                     h[h[p].lchild].code = h[p].code + '0';
                           h[h[p].rchild].code = h[p].code + '1';}
                           p--;
 }
    for (int temp = 1;temp<=nozero_num;temp++) cout<<h[temp].data<<"    "<<h[temp].code<<endl;
}
int main(int argc, char *argv[])
{
    vector<node> weights;
    int N;
    cout<<"请输入要编码的字符个数:"<<endl; 
    cin>>N;
    cout<<"请输入相应的字符以及其概率:"<<endl; 
    while(N>0)
    {
              node n;
              cout<<"字符:"; cin>>n.data;
              cout<<"概率:"; cin>>n.weight;
              weights.push_back(n); 
              N--;
    }
    cout<<"所得编码为:"<<endl;
    code(weights);
    
    system("PAUSE");
    return EXIT_SUCCESS;
}

3 楼

后面这个程序太半吊子了……建议你不要学习这种风格……

我来回复

您尚未登录,请登录后再回复。点此登录或注册