#include
#include
#include
typedef struct Node {
char data;
int freq;
struct Node* left, * right;
} Node;
typedef struct Heap {
int size;
Node* arr[100];
} Heap;
Heap* createHeap() {
Heap* h = (Heap*)malloc(sizeof(Heap));
h->size = 0;
return h;
}
void insertHeap(Heap* h, Node* node) {
h->size++;
int i = h->size;
while (i > 1 && node->freq < h->arr[i / 2]->freq) {
h->arr[i] = h->arr[i / 2];
i /= 2;
}
h->arr[i] = node;
}
Node* extractMin(Heap* h) {
Node* min = h->arr[1];
h->arr[1] = h->arr[h->size];
h->size--;
int i = 1;
while (1) {
int smallest = i;
int left = 2 * i;
int right = 2 * i + 1;
if (left <= h->size && h->arr[left]->freq < h->arr[smallest]->freq) {
smallest = left;
}
if (right <= h->size && h->arr[right]->freq < h->arr[smallest]->freq) {
smallest = right;
}
if (smallest != i) {
Node* temp = h->arr[smallest];
h->arr[smallest] = h->arr[i];
h->arr[i] = temp;
i = smallest;
}
else {
break;
}
}
return min;
}
Node* buildHuffmanTree(char* str) {
int freq[256] = { 0 };
for (int i = 0; str[i]; i++) {
freq[(int)str[i]]++;
}
Heap* h = createHeap();
for (int i = 0; i < 256; i++) {
if (freq[i]) {
Node* node = (Node*)malloc(sizeof(Node));
node->data = (char)i;
node->freq = freq[i];
node->left = node->right = NULL;
insertHeap(h, node);
}
}
while (h->size > 1) {
Node* left = extractMin(h);
Node* right = extractMin(h);
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = '\0';
newNode->freq = left->freq + right->freq;
newNode->left = left;
newNode->right = right;
insertHeap(h, newNode);
}
Node* root = extractMin(h);
free(h);
return root;
}
void printHuffmanCodes(Node* root, int arr[], int top) {
if (root->left) {
arr[top] = 0;
printHuffmanCodes(root->left, arr, top + 1);
}
if (root->right) {
arr[top] = 1;
printHuffmanCodes(root->right, arr, top + 1);
}
if (!(root->left) && !(root->right)) {
printf("%c: ", root->data);
for (int i = 0; i < top; i++) {
printf("%d", arr[i]);
}
printf("\n");
}
}
typedef struct {
char character;
char code[256];
} Code;
void generateCodes(Node* root, int arr[], int top, Code* codes, int* codeIndex) {
if (root->left) {
arr[top] = 0;
generateCodes(root->left, arr, top + 1, codes, codeIndex);
}
if (root->right) {
arr[top] = 1;
generateCodes(root->right, arr, top + 1, codes, codeIndex);
}
if (!(root->left) && !(root->right)) {
codes[*codeIndex].character = root->data;
for (int i = 0; i < top; i++) {
codes[*codeIndex].code[i] = '0' + arr[i];
}
codes[*codeIndex].code[top] = '\0';
(*codeIndex)++;
}
}
void encode(Node* root, char* input, char** output) {
Code codes[256];
int arr[100], top = 0, codeIndex = 0;
generateCodes(root, arr, top, codes, &codeIndex);
int encodedLength = 0;
for (int i = 0; input[i]; i++) {
for (int j = 0; j < codeIndex; j++) {
if (input[i] == codes[j].character) {
encodedLength += strlen(codes[j].code);
break;
}
}
}
*output = (char*)malloc((encodedLength + 1) * sizeof(char));
int outputIndex = 0;
for (int i = 0; input[i]; i++) {
for (int j = 0; j < codeIndex; j++) {
if (input[i] == codes[j].character) {
strcpy_s(*output + outputIndex, encodedLength + 1 - outputIndex, codes[j].code);
outputIndex += strlen(codes[j].code);
break;
}
}
}
(*output)[outputIndex] = '\0';
}
void decode(Node* root, char* input, char* output) {
Node* current = root;
int outputIndex = 0;
for (int i = 0; input[i]; i++) {
current = input[i] == '0' ? current->left : current->right;
if (!(current->left) && !(current->right)) {
output[outputIndex++] = current->data;
current = root;
}
}
output[outputIndex] = '\0';
}
int main() {
char input[100], binaryInput[100];
printf("输入一串字符: ");
fgets(input, sizeof(input), stdin);
input[strcspn(input, "\n")] = '\0';
Node* root = buildHuffmanTree(input);
printf("生成的哈夫曼编码: \n");
int arr[100], top = 0;
printHuffmanCodes(root, arr, top);
char* encoded;
encode(root, input, &encoded);
printf("输入字符串的哈夫曼编码: %s\n", encoded);
int validInput;
do {
validInput = 1;
printf("输入一串 01 字符串(需为上述编码的一部分或全部): ");
fgets(binaryInput, sizeof(binaryInput), stdin);
binaryInput[strcspn(binaryInput, "\n")] = '\0';
if (strstr(encoded, binaryInput) == NULL) {
printf("输入不正确,请重新输入。\n");
validInput = 0;
}
} while (!validInput);
char output[100];
decode(root, binaryInput, output);
printf("解码后的字符: %s\n", output);
free(encoded);
return 0;
}