|
发表于 2024-6-26 09:59:20
|
显示全部楼层
本帖最后由 小甲鱼的二师兄 于 2025-1-17 19:04 编辑
主要问题出在 dayin 函数的实现中。
在判断叶子节点时存在逻辑错误,导致没有正确打印字符的编码。
修复后的完整代码如下:
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define N 30
- #define MAX 2 * N - 1
- typedef struct HMtree {
- double weight;
- char s;
- int parent, rchild, lchild;
- } HMtree, HM[MAX + 1];
- void selectMin(HM ht, int x, int* m1, int* m2) {
- double min1 = 999;
- double min2 = 999;
- int j;
- for (j = 1; j <= x; j++) {
- if (ht[j].weight < min1 && ht[j].parent == 0) {
- min1 = ht[j].weight;
- *m1 = j;
- }
- }
- int k;
- for (k = 1; k <= x; k++) {
- if (ht[k].weight < min2 && k != *m1 && ht[k].parent == 0) {
- min2 = ht[k].weight;
- *m2 = k;
- }
- }
- }
- // 构建哈夫曼树
- void CreatHM(HM ht, int n) {
- int i;
- for (i = n + 1; i <= 2 * n - 1; i++) {
- int m1, m2;
- selectMin(ht, i - 1, &m1, &m2);
- ht[i].weight = ht[m1].weight + ht[m2].weight;
- ht[i].lchild = m1;
- ht[i].rchild = m2;
- ht[i].parent = 0;
- ht[m1].parent = i;
- ht[m2].parent = i;
- }
- }
- // 哈夫曼编码
- void HMcoding(HM ht, char** hc, int n) {
- char* cd = (char*)malloc(n * sizeof(char));
- cd[n - 1] = '\0';
- int now = 1;
- int p = 0;
- int start;
- int i = 0;
- while (i < n) {
- start = n - 1;
- now = i + 1;
- p = ht[now].parent;
- while (p != 0) {
- start--;
- if (ht[p].lchild == now) {
- cd[start] = '0';
- } else {
- cd[start] = '1';
- }
- now = p;
- p = ht[now].parent;
- }
- hc[i] = (char*)malloc((n - start + 1) * sizeof(char)); // 改为从 0 开始
- strcpy(hc[i], &cd[start]);
- i++;
- }
- free(cd);
- }
- // 先序打印
- void dayin(HM ht, char** hc, int index) {
- if (index >= 1) {
- if (ht[index].lchild == 0 && ht[index].rchild == 0) { // 叶子节点
- printf("%c:%s\n", ht[index].s, hc[index - 1]); // 索引从 0 开始
- return;
- }
- // 遍历左子树
- dayin(ht, hc, ht[index].lchild);
- // 遍历右子树
- dayin(ht, hc, ht[index].rchild);
- }
- }
- // 在生成的树里查找目标
- void chaHM(HM ht, int n, char* pwd) {
- printf("original:");
- int len = strlen(pwd);
- int i = 0;
- int node = 2 * n - 1;
- while (i < len) {
- if (pwd[i] == '0') {
- node = ht[node].lchild;
- i++;
- if (ht[node].lchild == 0 && ht[node].rchild == 0) { // 到达叶子节点
- printf("%c", ht[node].s);
- node = 2 * n - 1;
- }
- } else if (pwd[i] == '1') {
- node = ht[node].rchild;
- i++;
- if (ht[node].lchild == 0 && ht[node].rchild == 0) { // 到达叶子节点
- printf("%c", ht[node].s);
- node = 2 * n - 1;
- }
- } else { // 非法输入
- printf("\nError: Invalid character in encoded string.\n");
- return;
- }
- }
- printf("\n");
- }
- int main() {
- HM ht;
- int n; // 字符个数
- printf("Enter the number of characters:\n");
- scanf("%d", &n);
- getchar();
- char* hc[N]; // 动态调整大小,索引从 0 开始
- int i;
- printf("Enter characters and their weights (format: <char> <weight>):\n");
- for (i = 1; i <= n; i++) {
- scanf("%c %lf", &ht[i].s, &ht[i].weight);
- getchar();
- ht[i].lchild = 0;
- ht[i].rchild = 0;
- ht[i].parent = 0;
- }
- char pwd[99];
- printf("Enter the encoded string:\n");
- scanf("%s", pwd);
- CreatHM(ht, n);
- HMcoding(ht, hc, n);
- printf("Huffman Codes:\n");
- dayin(ht, hc, 2 * n - 1);
- chaHM(ht, n, pwd);
- // 释放动态分配的内存
- for (i = 0; i < n; i++) {
- free(hc[i]);
- }
- return 0;
- }
复制代码
|
|