//==========HaffmanTree & HaffmanCode===============
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
#define Status int
#define OK 1
#define ERROR 0
#define BOOLEAN int
#define TRUE 1
#define FALSE 0
#define OVERFLOW -1
#define MAXSIZE 200
#define MAX_WEIGHT 0X7f7f7f7f
#define N 26
#define maxn 10000
//---------HaffmanTree & HaffmanCode 的存储表示------------------
typedef struct {
unsigned int weight;
unsigned int parent, lchild, rchild;
}HTNode, *HuffmanTree;//动态分配数组存储HuffmanTree
typedef char * *HuffmanCode;//动态分配数组存储HuffmanCode Table
//----------HuffmanTree操作的函数声明-----------
//void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n);
void generateFile();
void HuffmanCoding(HuffmanTree &HT, char HC[][N], int *w, int n);
void Select(HuffmanTree HT, int i, int *s1, int *s2);
HTNode HTNodeAssignment(int w, int parent, int lchild, int rchild);
int getWight(int n, int w[]);
void saveHCtoFile(char HC[][N]);
void buildCode(char HC[][N]);
int decode(char HC[][N]);//解码
//===============================主函数======================================
int main() {
//paste your code here
HuffmanTree HT = NULL;
char HC[N + 1][N];
//HuffmanCode HC = NULL;
int w[N] = { 5,29,7,8,14,23,3,11 };//w数组存放各个字符的权值
int n = N;
generateFile();
getWight(n, w);//printf("%d\n", n);//也可能是一牵涉到文件读写就要出错
HuffmanCoding(HT, HC, w, n);
saveHCtoFile(HC);//可以不要
buildCode(HC);
decode(HC);
// for (int i = 1; i <= n; i++) {
// printf("%s\n", HC[i]);
// }//输出编码
//while (1);
return 0;
}
//--------HuffmanTree操作的函数实现---------------------------------------
HTNode HTNodeAssignment(int w, int parent, int lchild, int rchild) {
HTNode tmp;
tmp.weight = w;
tmp.parent = parent;
tmp.lchild = lchild;
tmp.rchild = rchild;
return tmp;
}
void HuffmanCoding(HuffmanTree &HT, char HC[][N], int *w, int n) {
//w存放n个字符的权值(均>0),构造HuffmanTree HT,并求出n个HuffmanCode HC
if (n <= 1) return;
int m = 2 * n - 1;
HT = NULL;
HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode));//0号单元未用
if (HT == NULL) exit(OVERFLOW);
//HuffmanTree p=HT;
int i;// printf("%d\n", n);//VS编译器有毒呀,n值理论上是不会变的呀
for (i = 1; i <= n; ++i, ++w) {
//*p=HTNodeAssignment(*w,0,0,0);
HT[i] = HTNodeAssignment(*w, 0, 0, 0);
}
for (; i <= m; ++i) {
HT[i] = HTNodeAssignment(0, 0, 0, 0);
}
for (i = n + 1; i <= m; i++) {//建立HuffmanTree
//在HT[1..i)选择parent为0且weigh最小的两个节点,其序号分别为s1,s2(small)
int s1, s2;
Select(HT, i, &s1, &s2);//1.。i不包括i,即左闭右开
//printf("%d: %d %d\n",i,s1,s2);//观察函数选择是否有问题
HT[s1].parent = HT[s2].parent = i;
HT[i].lchild = s1;
HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
}
//for(int i=1;i<=m;++i)printf("%d\t%d\t%d\n",i,HT[i].parent,HT[i].weight);//debug
//---从叶子到根逆求每个字符的HuffmanCode
//HC = (HuffmanCode)malloc((n + 1) * sizeof(char));//分配n个字符编码的头指针向量
char *cd;
cd = (char*)malloc(n * sizeof(char));//求分配编码的工作空间
cd[n - 1] = '\0';//编码结束符,最长编码长度n-1
for (i = 1; i <= n; ++i) {//逐个字符求HuffmanCode
int start = n - 1;
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
//if (i == 1) printf("bibububu:%s\n", HC[1]);
//for(int cnt=0;start<=n-1;++start) HC[i][cnt++]=cd[start];
//printf("%d\t%d\t%s\n", i, n - start, cd + start);
//除了HC[1]复制不正常,其他都正常
}
//printf("bibububu:%s\n", HC[1]);
free(cd); cd = NULL;//一释放就要出事
}
void Select(HuffmanTree HT, int i, int *s1, int *s2) { //[0,i
int min1 = MAX_WEIGHT, min2 = MAX_WEIGHT;
BOOLEAN flag = FALSE;
for (int j = 1; j= N-1) return record;//已匹配的01个数
}
fclose(fp);
fclose(fptr);
return -1;
}//fc比较都找不到差异,我还能说什么
void generateFile() {
FILE *fp;
char ch, *p = "data.txt";
fp = fopen(p, "wt");
srand(time(NULL));
for (int i = 0; i