该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
#include
#include
#include
#include
using namespace std
typedef int ElemType;
typedef int Status;
typedef int Boolean;
typedef struct {
int weight,id;
unsigned int parent, lchild,rchild;
}HTNode, *HuffmanTree;/*动态分配数组储存哈夫曼树---HT*/
typedef char * * HuffmanCode;/*动态分配数组储存哈夫曼编码表----HC*/
typedef struct{
int w;
char c;
}temp;//储存字符和数字
void Select(HuffmanTree & HT, int tag, int & s1, int &s2)
{
int min = 1e9, pos = -1;
for(int i = 1; i<=tag;++i){
if(HT[i].weight
min = HT[i].weight;
pos = i;
}
}
s2 = pos;
HT[pos].parent = tag+1;
min = 10e9, pos = -1;
for(int i = 1;i<=tag;++i){
if(HT[i].weight
min = HT[i].weight;
pos = i;
}
}
s1 = pos;
HT[pos].parent = tag+1;
}
void HuffmanCoding(HuffmanTree & HT, HuffmanCode &HC, int *w , int n)
/*W存放n个字符的权值(均大于0),构造哈夫曼树,并求出n个字符的哈夫曼编码hc*/
{
if(n<=1) return;
int m = 2 * n -1 ;//所有节点数
HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode));//申请储存空间,0号单元未用
int i = 1;
HuffmanTree p = HT;
for(;i<=n; ++i,++p,++w){
HT[i] = {*w,i,0,0,0};
}
for(i = n+1 ;i<=m;++i,++p)
HT[i]= {0,i,0,0,0};
for(int i = n+1;i<=m;++i){//建立哈夫曼树
int s1, s2;
Select(HT,i-1,s1,s2);//在HT[1.i-1]选择parent为0且weight最小的两个节点,其序号为s1和s2.
if(s2<=n) swap(s1,s2);//HT[s1].parent = i; HT[s2].parent = i;交换S1 ,S2
HT[i].lchild = s1; HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
}
/*----------从子叶到跟逆向求每个字符的哈夫曼编码*/
HC = (HuffmanCode)malloc((n+1) * sizeof(char *));/*分配n个字符编码的头指针向量*/
char * cd = (char *)malloc( n * sizeof(char));//分配求编码的工作空间
cd[n-1] = '\0';//编码结束符
for(int i = 1; i<=n;++i){//逐个字符求哈夫曼编码
int start = n-1;//编码结束符位置
unsigned int f = HT[i].parent;
for( int c = i,f = HT[i].parent; f!=0 ;c = f,f = HT[f].parent)//从子叶到根逆序求编码
if(HT[f].lchild == c) cd[--start] = '0';
else cd[--start] = '1';
HC[i] = (char*)malloc((n-start) * sizeof(char));//为第i个字符编码分配空间
strcpy(HC[i],&cd[start]);//从cd复制编码串到 HC
}
free(cd);//释放工作空间
}
void uncoding(HuffmanTree & HT, int n,char * s)
{
char str[100000] = "9e9";
printf("|"); printf(" 4.请输入想要解码的01串 ") ;printf("| \n");
scanf("%s",str);
printf("|"); printf(" 5.译码的结果为 ") ;printf("| \n");
int len = strlen(str);
HuffmanTree t = &HT[2*n-1];//叶子节点数
for(int i = 0; i
if(str[i] == '0'){
t = &HT[t->lchild];
}else{
t = &HT[t->rchild];
}
if(t->id<=n){
printf("%c",s[t->id-1]);
t = &HT[2*n-1];//所有节点数
continue;
}
}
printf(" \n");
}
void Paint()
{
int sel=0;
cout<
cout<
cout<
cout<
cout<
cout<
printf("|"); printf(" The Experiment Of Tree ") ;printf("|\n");
printf("|"); printf(" Huffman ") ;printf("|\n");
printf("|"); printf(" Date:2019/1/8 ") ;printf("|\n");
}
int main()
{
Paint();
HuffmanTree HT ;
HuffmanCode HC;
printf("|"); printf(" 1.请输入想要编码的字符 ") ;printf("|\n");
char str[100000] = { };
scanf("%s",str);
printf("|"); printf(" 2.请依次输入字符的频率(空格键隔开) ") ;printf("|\n");
int fre[100000] = { };
for(int i = 0; i
temp t[100000];
for(int i = 0; i
{
t[i].w = fre[i];
t[i].c = str[i];
}
HuffmanCoding(HT,HC,fre,strlen(str));
printf("|"); printf(" 3.编码的结果为 ") ;printf("|\n");
for(int i = 1; i<=strlen(str) ;++i)
{
printf("%c : ",t[i-1].c);
printf("%s\n",HC[i]);
}
printf("\n");
uncoding(HT,strlen(str),str);
return 0;
}
解码的01串 111 为什么是s,第三个 1, 去哪了?,如何修修改这个问题?