大二时期数据结构课程的实验,代码可以直接运行,希望可以给大家提供到帮助。
实验目的
- 掌握二叉树的定义。
- 掌握哈夫曼树和哈夫曼编码与译码算法的实现。
实验内容
实现一个哈夫曼编码系统,系统包括以下功能:
- 字符信息统计:读取待编码的源文件SourceFile.txt(例如dsadksahudkhasudhsahdsJSGFSDHFUHISUDHF),统计出现的字符及其频率。
- 建立哈夫曼树:根据统计结果建立哈夫曼树。
- 建立哈夫曼码表:利用得到的哈夫曼树,将各字符对应的编码表保存在文件Code.txt中。
- 对源文件进行编码:根据哈夫曼码表,将SourceFile.txt中的字符转换成相应的编码文件ResultFile.txt。
- 对源文件进行译码:根据哈夫曼码表,将对任意一个给定的由01组成的文件编码转换成相应的字符。
数据输入与输出要求
采用文件。
数据结构设计
哈夫曼树。
程序核心代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MAXSIZE 100
typedef int Status;
typedef int ElemType;
typedef struct
{
int weight;
int parent, lchild, rchild;
}HTNode, *HuffmanTree;
typedef char** HuffmanCode;
int statistic[27];
char alphabet[27] = {' ', 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', 'p','q','r','s','t','u','v','w','x','y','z' };
int n = 27;
void Count()
{
FILE* fp;
char letter;
int i, k, w, i1 = 1;
for (k = 0; k < 27; k++)
{
statistic[k] = 0;
}
fp = fopen("C://Users//86133//Desktop//SourceFile.txt", "r");
if (fp == NULL)
{
printf("无法发现文件");
exit(0);
}
while ((letter = fgetc(fp)) != EOF)
{
if (letter >= 'A' && letter <= 'Z')
letter = letter + 32;
i = letter - 96;
statistic[i] = statistic[i] + 1;
}
for (i = 1; i <= 27; i++)
{
if (statistic[i1] == 0)
{
w = i1;
while(w <= 27)
{
statistic[w] = statistic[w + 1];
alphabet[w] = alphabet[w + 1];
w++;
}
i1--;
}
i1++;
}
i = 1;
//这儿应该返回新的n
while (i <= 27)
{
if (statistic[i] == 0)
n--;
i++;
}
fclose(fp);
}
void Select_min(HuffmanTree HT, int j, int &s1, int &s2)
{
int i;
int min1 = 1000;
int min2 = 1000;
for (i = 1; i <= j; i++)
{
if (HT[i].weight < min1 && HT[i].parent == 0)
{
min1 = HT[i].weight;
s1 = i;
}
}
for (i = 1; i <= j; i++)
{
if (i != s1 && HT[i].parent == 0)
{
if (HT[i].weight < min2)
{
min2 = HT[i].weight;
s2 = i;
}
}
}
}
//n得加1
HuffmanTree CreatHuffmanTree()
{
if (n <= 1)
exit(0);
int m, i, k;
int b = 0, c = 0;
m = 2 * n - 1;
HuffmanTree HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode));
if (!HT)
{
printf("哈夫曼树创建失败");
exit(0);
}
for (i = 1; i <= m; i++)
{
HT[i].lchild = 0;
HT[i].rchild = 0;
HT[i].parent = 0;
HT[i].weight = 0;
}
for (i = 1; i <= n; i++)
HT[i].weight = statistic[i];
k = n;
while(k < m)
{
Select_min(HT, k, b, c);
HT[b].parent = k + 1;
HT[c].parent = k + 1;
HT[k + 1].lchild = b;
HT[k + 1].rchild = c;
HT[k + 1].weight = HT[b].weight + HT[c].weight;
k++;
}
printf("哈夫曼树构造完成\n");
return HT;
}
void CreatHuffmanCode(HuffmanTree HT, HuffmanCode& HC)
{
char* cd = (char*)malloc(n * sizeof(char));
HC = (HuffmanCode)malloc((n + 1) * sizeof(char*));
int i, start, c, f;
cd[n - 1] = '\0';
for (i = 1; i <= n; i++)
{
start = n - 1;
c = i;
f = HT[i].parent;
while (f)
{
if (HT[f].lchild == c)
cd[--start] = '0';
else
cd[--start] = '1';
c = f;
f = HT[f].parent;
}
HC[i] = (char*)malloc((n - start) * sizeof(char));
strcpy(HC[i], &cd[start]);
}
FILE* fp;
fp = fopen("C://Users//86133//Desktop//ResultFile.txt", "w");
if (fp == NULL)
{
printf("无法发现文件");
exit(0);
}
for (i = 1; i <= n; i++)
{
fprintf(fp, "%c ", alphabet[i]);
fprintf(fp, "%s", HC[i]);
fprintf(fp, "\n");
}
}
void DecodingHumanCode(HuffmanTree HT) //译码并不是看AB什么对应的编码,还是直接用树
{
FILE* fp;
int i = 0, k;
int temp = 2 * n - 1;
char c;
int b;
int a[100];
fp = fopen("C://Users//86133//Desktop//Test.txt", "r");
if (fp == NULL)
{
printf("无法发现文件");
exit(0);
}
while ((b = fgetc(fp)) != EOF)
{
a[i] = b - 48;
i++;
}
fclose(fp);
for(k = 0; k < i; k++)
{
if (a[k] == 0)
{
if (HT[temp].lchild != 0)
temp = HT[temp].lchild;
if (HT[temp].lchild == 0 && HT[temp].rchild == 0)
{
c = alphabet[temp];
printf("%c", c);
temp = 2 * n - 1;
}
}
if (a[k] == 1)
{
if (HT[temp].rchild != 0)
temp = HT[temp].rchild;
if (HT[temp].lchild == 0 && HT[temp].rchild == 0)
{
c = alphabet[temp];
printf("%c", c);
temp = 2 * n - 1;
}
}
}
}
int main()
{
int i;
HuffmanTree HT;
HuffmanCode HC;
Count();
HT = CreatHuffmanTree();
for (i = 1; i <= (2 * n -1); i++)
{
printf("%d ", i);
printf("%d ", HT[i].weight);
printf("%d ", HT[i].parent);
printf("%d ", HT[i].lchild);
printf("%d\n", HT[i].rchild);
}
CreatHuffmanCode(HT, HC);
printf("编码完成\n");
for (i = 1; i <= n; i++)
{
printf("%c ", alphabet[i]);
printf("%s\n", HC[i]);
}
printf("解码完成\n");
DecodingHumanCode(HT);
return 0;
}