```c
#include <conio.h>
#include <stdio.h>
#include <process.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <fstream>
#define max 100
#include <iostream>
using namespace std;
#define supermax 100000
struct BiTNode
{ // 二叉树结点类型
char symbol;
int data; // 数据
int tem1, tem2; // 辅助数据(实习题不用)
BiTNode *left; // 左子树指针
BiTNode *right; // 右子树指针
};
struct HuffmanCode {
char character;
char* code;
} ;
void getWidth1(BiTNode *Tree, int depth, int shift, char map[max*2][max*2])
{
int i;
if (Tree->left != NULL)
{
getWidth1(Tree->left, depth+1, shift, map);
Tree->tem1 = Tree->left->tem1 + Tree->left->tem2 + 1;
for (i=(Tree->left->tem1+shift)*2; i<shift*2; i=i+2)
{
map[depth*2+1][i]='-';
map[depth*2+1][i+1]='-';
}
}
else Tree->tem1 = 0;
if (Tree->right != NULL)
{
getWidth1(Tree->right, depth+1, shift+Tree->tem1+1, map);
Tree->tem2 = Tree->right->tem1 + Tree->right->tem2 + 1;
}
else Tree->tem2 = 0;
for (i=shift*2; i<(Tree->tem1+shift)*2; i++)
map[depth*2][i]=' ';
map[depth*2][(Tree->tem1+shift)*2]=(char)(Tree->data / 1000 +48);
map[depth*2][(Tree->tem1+shift)*2+1]=(char)(Tree->data / 100 % 10 +48);
map[depth*2][(Tree->tem1+shift)*2+2]=(char)(Tree->data / 10 % 10 +48);
map[depth*2][(Tree->tem1+shift)*2+3]=(char)(Tree->data %10 +48);
if (Tree->data<1000)
{
map[depth*2][(Tree->tem1+shift)*2]=' ';
if (Tree->data<100)
{
map[depth*2][(Tree->tem1+shift)*2+1]=map[depth*2][(Tree->tem1+shift)*2+2];
map[depth*2][(Tree->tem1+shift)*2+2]=map[depth*2][(Tree->tem1+shift)*2+3];
map[depth*2][(Tree->tem1+shift)*2+3]=' ';
if (Tree->data<10)
map[depth*2][(Tree->tem1+shift)*2+1]=' ';
}
}
if (Tree->left != NULL)
{
map[depth*2+1][(Tree->left->tem1+shift)*2+1]=(char)0xa9;
map[depth*2+1][(Tree->left->tem1+shift)*2+2]=(char)0xb0;
map[depth*2+1][(Tree->tem1+shift)*2+1]=(char)0xa9;
map[depth*2+1][(Tree->tem1+shift)*2+2]=(char)0xbc;
for (i=(Tree->left->tem1+shift)*2+3; i<(Tree->tem1+shift)*2; i=i+2)
{
map[depth*2+1][i]=(char)0xa9;
map[depth*2+1][i+1]=(char)0xa4;
}
}
if (Tree->right != NULL)
{
map[depth*2+1][(Tree->tem1+shift)*2+1]=(char)0xa9;
map[depth*2+1][(Tree->tem1+shift)*2+2]=(char)0xb8;
map[depth*2+1][(Tree->tem1+Tree->right->tem1+shift)*2+3]=(char)0xa9;
map[depth*2+1][(Tree->tem1+Tree->right->tem1+shift)*2+4]=(char)0xb4;
for (i=(Tree->tem1+shift)*2+3; i<(Tree->tem1+Tree->right->tem1+shift)*2+2; i=i+2)
{
map[depth*2+1][i]=(char)0xa9;
map[depth*2+1][i+1]=(char)0xa4;
}
}
if (Tree->left != NULL && Tree->right != NULL)
{
map[depth*2+1][(Tree->tem1+shift)*2+1]=(char)0xa9;
map[depth*2+1][(Tree->tem1+shift)*2+2]=(char)0xd8;
}
}
//生成文件Map.txt,显示以Tree为根指针的二叉树
void showBinTree1(BiTNode *Tree)
{
char map[max*2][max*2];
ofstream out;
int i,j,k;
out.open("Map.txt");
if (Tree == NULL)
{
out<<"空树";
out.close();
return;
}
for (i=0; i<max*2; i++)
for (j=0; j<max*2; j++)
map[i][j]=' ';
getWidth1(Tree,0,0,map);
for (i=0; i<max*2; i++)
{
k=max*2-1;
while (k>=0 && map[i][k]==' ')
k--;
for (j=0; j<=k; j++)
out<<map[i][j];
out<<"\n";
}
out.close();
}
BiTNode *createNode(int data, char symbol) {
BiTNode* newNode = (BiTNode *)malloc(sizeof(BiTNode));
newNode->data = data;
newNode->symbol = symbol;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
//构建哈夫曼树
BiTNode *buildHuffmanTree(char symbols[], int frequencies[], int size) {
// 创建叶子节点
BiTNode** nodes = (BiTNode**)malloc(size * sizeof(BiTNode*));
for (int i = 0; i < size; i++) {
nodes[i] = createNode(frequencies[i], symbols[i]);
}//这里要考,理论上有2n-1个节点
// 构建哈夫曼树
while (size > 1) {
BiTNode *leftChild = NULL;
BiTNode *rightChild = NULL;
int minIndex1 = -1;
int minIndex2 = -1;
// 找到频率最小的两个节点
for (int i = 0; i < size; i++) {
if (minIndex1 == -1 || nodes[i]->data < nodes[minIndex1]->data) {
minIndex2 = minIndex1;
minIndex1 = i;
}
else if (minIndex2 == -1 || nodes[i]->data < nodes[minIndex2]->data) {
minIndex2 = i;
}
}
// 创建新节点作为它们的父节点
leftChild = nodes[minIndex1];
rightChild = nodes[minIndex2];
BiTNode *parentNode = createNode(leftChild->data + rightChild->data, '\0');
parentNode->left = leftChild;
parentNode->right = rightChild;
// 删除两个子节点
//错误写法
/*
if (minIndex1 < minIndex2) {
nodes[minIndex1] = parentNode;
for (int i = minIndex2; i < size - 1; i++) {
nodes[i] = nodes[i + 1];
}
}
else if(minIndex2 < minIndex1){
nodes[minIndex2] = parentNode;
int i = minIndex1;
for (int i = minIndex1; i < size-1; i++) {//在这里如果没有int i = minIndex1或者int k = size,就会出现赋值错误
nodes[i] = nodes[i + 1];
}
}
*/
int k = size;
// 更新节点数组
if (minIndex1 < minIndex2) {
nodes[minIndex1] = parentNode;
for (int i = minIndex2; i < k - 1; i++) {
nodes[i] = nodes[i + 1];
}
}
else if(minIndex2 < minIndex1){//交换nodes里边的位置从大到小,并将parent存入
nodes[minIndex2] = parentNode;
int i = minIndex1;
for (i ; i < k-1; i++) {//在这里如果没有int i = minIndex1或者int k = size,就会出现赋值错误
nodes[i] = nodes[i + 1];
}
}
size--;
}
// 返回根节点
return nodes[0];
}
void sortNodes(struct BiTNode** nodes, int size) {
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i - 1; j++) {
if (nodes[j]->data < nodes[j + 1]->data) {
struct BiTNode* temp = nodes[j];
nodes[j] = nodes[j + 1];
nodes[j + 1] = temp;
}
}
}
}
// 构建哈夫曼树
// BiTNode* buildHuffmanTree(char symbols[], int frequencies[], int size) {
// // 创建叶子节点
// BiTNode** nodes = (BiTNode**)malloc(size * sizeof(BiTNode*));
// for (int i = 0; i < size; i++) {
// nodes[i] = createNode(frequencies[i], symbols[i]);
// }
// // 对节点按照频率从大到小排序(可以使用冒泡、插入或快速排序等算法)
// for (int i = 0; i < size - 1; i++) {
// for (int j = 0; j < size - i - 1; j++) {
// if (nodes[j]->data < nodes[j + 1]->data) {
// // 交换节点
// BiTNode* temp = nodes[j];
// nodes[j] = nodes[j + 1];
// nodes[j + 1] = temp;
// }
// }
// }
// // 构建哈夫曼树
// while (size > 1) {
// BiTNode *leftChild = nodes[size - 1]; // 取最后两个节点(频率最小的)
// BiTNode *rightChild = nodes[size - 2];
// BiTNode *parentNode = createNode(leftChild->data + rightChild->data, '\0');
// parentNode->left = leftChild;
// parentNode->right = rightChild;
// // 删除已经合并的两个子节点
// free(leftChild);
// free(rightChild);
// // 更新节点数组,保持有序
// int insertIndex = size - 2;
// while (insertIndex > 0 && parentNode->data < nodes[insertIndex - 1]->data) {
// nodes[insertIndex] = nodes[insertIndex - 1];
// insertIndex--;
// }
// nodes[insertIndex] = parentNode;
// size--;
// }
// // 返回根节点
// return nodes[0];
// }
// 释放哈夫曼树内存
void freeHuffmanTree(struct BiTNode* root) {
if (root) {
freeHuffmanTree(root->left);
freeHuffmanTree(root->right);
free(root);
}
}
// 打印哈夫曼编码
void printHuffmanCodes(BiTNode *root, int code[], int top) {
if (root->left) {
code[top] = 0;
printHuffmanCodes(root->left, code, top + 1);
}
if (root->right) {
code[top] = 1;
printHuffmanCodes(root->right, code, top + 1);
}
if (root->symbol != '\0') {
printf("%c: ", root->symbol);
for (int i = 0; i < top; i++) {
printf("%d", code[i]);
}
printf("\n");
}
}
void writeHuffmanCodesToFile(BiTNode *root, int code[], int top, FILE *file) {
if (root->left) {
code[top] = 0;
writeHuffmanCodesToFile(root->left, code, top + 1, file);
}
if (root->right) {
code[top] = 1;
writeHuffmanCodesToFile(root->right, code, top + 1, file);
}
if (!(root->left) && !(root->right)) {
// 叶子节点,表示字符和编码
fprintf(file, "%c: ", root->symbol);
for (int i = 0; i < top; i++) {
fprintf(file, "%d", code[i]);
}
fprintf(file, "\n");
}
}
// 读取哈夫曼编码文件并创建结构体数组
HuffmanCode* readHuffmanCodesFromFile(const char* filename, int* numCodes) {
FILE* file = fopen(filename, "r");
if (file == NULL) {
perror("无法打开文件");
exit(1);
}
// 假设哈夫曼编码文件的行数不超过 1000 行,你可以根据实际情况调整这个大小
const int maxLines = 1000;
HuffmanCode* huffmanCodes = (HuffmanCode*)malloc(maxLines * sizeof(HuffmanCode));
char line[100]; // 假设每行不超过 100 个字符
*numCodes = 0;
while (fgets(line, sizeof(line), file) != NULL) {
if (*numCodes >= maxLines) {
fprintf(stderr, "哈夫曼编码文件中的行数超过了预期的最大行数。\n");
fclose(file);
free(huffmanCodes);
exit(1);
}
// 解析每一行,假设格式为 "字符: 编码"
char character;
char code[100];
if (sscanf(line, "%c: %s", &character, code) == 2) {
huffmanCodes[*numCodes].character = character;
huffmanCodes[*numCodes].code = strdup(code);
(*numCodes)++;
}
}
fclose(file);
return huffmanCodes;
}
// 编码文本
char* encodeText(const char* text,HuffmanCode* nodes) {
int textLength = strlen(text);
char* encodedText = (char*)malloc(2 * sizeof(char)); // 预估编码后的长度
int encodedIndex = 0;
for (int i = 0; i < textLength; i++) {
char currentChar = text[i];
for (int j = 0; j < 27; j++) {
if (currentChar == nodes[j].character) {
strcat(encodedText, nodes[j].code);
encodedIndex += strlen(nodes[j].code);
break;
}
}
}
// encodedText[encodedIndex] = '\0';
return encodedText;
}
// 解码文本
char* decodeText(const char* encodedText, struct BiTNode* root) {
int encodedLength = strlen(encodedText);
char* decodedText = (char*)malloc(encodedLength * sizeof(char));
int decodedIndex = 0;
struct BiTNode* currentNode = root;
for (int i = 0; i < encodedLength; i++) {
if (encodedText[i] == '0') {
currentNode = currentNode->left;
} else if (encodedText[i] == '1') {
currentNode = currentNode->right;
}
if (currentNode->left == NULL && currentNode->right == NULL) {
decodedText[decodedIndex++] = currentNode->symbol;
currentNode = root;
}
}
decodedText[decodedIndex] = '\0';
return decodedText;
}
int main() {
char symbols[] = {' ','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 frequencies[] = {186,64, 23, 22, 32,
103,21,15,47,57,
1,5,32,20,20,
56,19,2,50,51,
55,30,10,11,2,
21,2};
int size = sizeof(symbols) / sizeof(symbols[0]);
BiTNode *root = buildHuffmanTree(symbols, frequencies, size);
int code[supermax];
int top = 0;
printHuffmanCodes(root, code, top);
showBinTree1(root);
FILE *codeFile = fopen("codefile.txt", "w");
if (codeFile == NULL) {
perror("无法打开文件");
return 1;
}
// int code[10000];
// top = 0;
// 将Huffman编码写入文件
writeHuffmanCodesToFile(root, code, top, codeFile);
// 关闭文件
fclose(codeFile);
//读取哈夫曼编码文件
int codeCount;
HuffmanCode *huffmanCodes = readHuffmanCodesFromFile("codefile.txt", &codeCount);
if (huffmanCodes == NULL) {
return 1;
}
const char* originalText = " MY FAVORITE " ;
char* encodedText = encodeText(originalText, huffmanCodes);
printf("Encoded Text: %s\n", encodedText);
char* decodedText = decodeText(encodedText, root);
printf("Decoded Text: %s\n", decodedText);
return 0;
}
哈夫曼树外加编码
最新推荐文章于 2024-09-06 10:38:06 发布