鱼C论坛

 找回密码
 立即注册
查看: 1025|回复: 2

花了2天写出来的,哪里有问题呀?

[复制链接]
发表于 2022-12-25 21:39:46 | 显示全部楼层 |阅读模式
60鱼币
X@RZ03KMHGQ{JT9P3QK5N(1.png
huffman.c
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>

  4. #include "huffman.h"
  5. #include "pQueue.h"

  6. void traverseTree(htNode *treeNode, hlTable **table, int k, char code[256]){
  7.         if(treeNode->left == NULL && treeNode->right == NULL){//目前位于叶结点
  8.                 code[k] = '\0';//结束字符串
  9.                 hlNode *aux = (hlNode *)malloc(sizeof(hlNode));//hlNode存放字符和对应的编码值;code存放编码值;symbol存放字符
  10.                 aux->code = (char *)malloc(sizeof(char)*(strlen(code)+1));
  11.                 strcpy(aux->code,code);//将编码拷贝到结点里
  12.                 aux->symbol = treeNode->symbol;
  13.                 aux->next = NULL;

  14.                 if((*table)->first == NULL){//aux是table的第一个结点
  15.                         (*table)->first = aux;//first指向第一个结点
  16.                         (*table)->last = aux;//last指向最后一个
  17.                 }
  18.                 else{
  19.                         (*table)->last->next = aux;
  20.                         (*table)->last = aux;
  21.                 }
  22.         }
  23.        
  24.         if(treeNode->left != NULL){//左指针不为空,向左编码为0
  25.                 code[k]='0';//确定当前层数的编码值
  26.                 traverseTree(treeNode->left,table,k+1,code);//递归到最底层
  27.                
  28.         }
  29.         if(treeNode->right != NULL){//向右编码为1
  30.                 code[k]='1';
  31.                 traverseTree(treeNode->right,table,k+1,code);
  32.                
  33.         }
  34. }

  35. hlTable * buildTable(htTree * huffmanTree){
  36.         hlTable *table = (hlTable *)malloc(sizeof(hlTable));
  37.         table->first = NULL;//malloc获取hlTable大小的空间,存放字符对应的编码
  38.         table->last = NULL;
  39.        
  40.         char code[256];
  41.         int i, k = 0;

  42.         traverseTree(huffmanTree->root, &table, k, code);//huffmanTree->root:霍夫曼树的根结点;table:存放编码的指针;k:目前位于第几层;code:存放每一层得到的0和1
  43.         return table;
  44. }

  45. htTree * buildTree(char *inputStr){//生成霍夫曼树,返回htree结点,指向根结点
  46.         int i;

  47.         int * probability = (int *)malloc(sizeof(int)*256);//Ascll码一共有八位;存放256个Ascll码,记录每一个字符出现的次数
  48.        
  49.         for(i = 0; i < 256; i++)//初始化每一项为0
  50.                 probability[i]=0;

  51.         for(i = 0; inputStr[i] != '\0'; i++)//统计带编码的字符串中各个字符出现的次数
  52.                 probability[(unsigned char) inputStr[i]]++;//(unsigned char)进行强调,没有也可以

  53.         pQueue * huffmanQueue;//huffmanQueue是pQueue类型的变量,队列的头指针
  54.         initPQueue(&huffmanQueue);//给头指针分配了空间

  55.         for(i = 0; i < 256; i++){//按优先级,出现次数,进行插入
  56.                 if(probability[i] != 0){//有出现过
  57.                         htNode *aux = (htNode *)malloc(sizeof(htNode));///分配一个树的结点
  58.                         aux->left = NULL;
  59.                         aux->right = NULL;
  60.                         aux->symbol = (char) i;
  61.                        
  62.                         addPQueue(&huffmanQueue, aux, probability[i]);//插入队列;huffmanQueue:头指针;aux:代插入的结点;probability[i]:(char)i出现的次数
  63.                 }
  64.         }

  65.         free(probability);//出现次数,使用完,没有了,释放掉

  66.         while(huffmanQueue->size!=1){//真正的生成一个霍夫曼树
  67.                 int priority = huffmanQueue->first->priority;//出现次数;权值
  68.                 priority += huffmanQueue->first->next->priority;//priority:前2个结点,权值相加

  69.                 htNode *left = getPQueue(&huffmanQueue);//声明一个left树结点
  70.                 htNode *right = getPQueue(&huffmanQueue);//getPQueue:从列表中获取

  71.                 htNode *newNode = (htNode *)malloc(sizeof(htNode));//前面2个结点
  72.                 newNode->left = left;//成为newNode的左右孩子结点
  73.                 newNode->right = right;//权值小的放左边

  74.                 addPQueue(&huffmanQueue, newNode, priority);//插入列表
  75.         }

  76.         htTree *tree = (htTree *) malloc(sizeof(htTree));//htTree:指向根结点

  77.         tree->root = getPQueue(&huffmanQueue);//huffmanQueue:根结点
  78.        
  79.         return tree;
  80. }

  81. void encode(hlTable *table, char *stringToEncode){//把字符串变为对应的编码,打印
  82.         int i;
  83.         hlNode *traversal;
  84.        
  85.         printf("\n输入的字符串 : \n%s\n编码后 : \n", stringToEncode);
  86.         for (i = 0; stringToEncode[i] != '\0'; i++){//对于字符串的每个元素遍历列表
  87.                 traversal = table->first;//一旦找到符号,我们就输出它的代码
  88.                 while (traversal->symbol != stringToEncode[i])
  89.                         traversal = traversal->next;
  90.                 printf("%s", traversal->code);
  91.         }

  92.         printf("\n");
  93. }

  94. void decode(htTree *tree, char *stringToDecode){
  95.         int i;
  96.         htNode *traversal = tree->root;

  97.         printf("\n输入字符串 : \n%s\n解码后 : \n",stringToDecode);

  98.         for(i = 0; stringToDecode[i] != '\0'; i++){
  99.                 if(traversal->left == NULL && traversal->right == NULL){
  100.                         printf("%c",traversal->symbol);
  101.                         traversal = tree->root;
  102.                 }
  103.                
  104.                 if(stringToDecode[i] == '0')
  105.                         traversal = traversal->left;

  106.                 if(stringToDecode[i] == '1')
  107.                         traversal = traversal->right;

  108.                 if(stringToDecode[i]!='0'&&stringToDecode[i]!='1'){
  109.                         printf("The input string is not coded correctly!\n");
  110.                         return;
  111.                 }
  112.         }

  113.         if(traversal->left == NULL && traversal->right == NULL)
  114.         {
  115.                 printf("%c",traversal->symbol);
  116.                 traversal = tree->root;
  117.         }

  118.         printf("\n");
  119. }
复制代码


pQueue.c
  1. #include "pQueue.h"

  2. #include <stdlib.h>

  3. #include <stdio.h>



  4. void initPQueue(pQueue **queue){

  5.         (*queue) = (pQueue *) malloc(sizeof(pQueue));//(*queue):队列头指针的地址

  6.         (*queue)->first = NULL;

  7.         (*queue)->size = 0;

  8.         return;

  9. }

  10. void addPQueue(pQueue **queue, TYPE val, unsigned int priority){

  11.         if((*queue)->size == MAX_SZ){

  12.                 printf("\n队列已经满了.\n");

  13.                 return;

  14.         }



  15.         pQueueNode *aux = (pQueueNode *)malloc(sizeof(pQueueNode));//申请空间

  16.         aux->priority = priority;//赋值,出现次数

  17.         aux->val = val;//val:树结点



  18.         if((*queue)->size == 0 || (*queue)->first == NULL){//如果是空队列

  19.                 aux->next = NULL;

  20.                 (*queue)->first = aux;

  21.                 (*queue)->size = 1;

  22.                 return;

  23.         }

  24.         else{

  25.                 if(priority <= (*queue)->first->priority){//优先级小于第一个结点,

  26.                         aux->next = (*queue)->first;

  27.                         (*queue)->first = aux;

  28.                         (*queue)->size++;

  29.                         return;

  30.                 }

  31.                 else{

  32.                         pQueueNode * iterator = (*queue)->first;//iterator:迭代器

  33.                         while(iterator->next!=NULL){

  34.                                 if(priority <= iterator->next->priority){

  35.                                         aux->next = iterator->next;

  36.                                         iterator->next = aux;

  37.                                         (*queue)->size++;

  38.                                         return;

  39.                                 }

  40.                                 iterator = iterator->next;

  41.                         }

  42.                         if(iterator->next == NULL){//是最大的。放在最后

  43.                                         aux->next = NULL;

  44.                                         iterator->next = aux;

  45.                                         (*queue)->size++;

  46.                                         return;

  47.                         }

  48.                 }

  49.         }

  50. }



  51. TYPE getPQueue(pQueue **queue){//从队列里面获取数据

  52.         TYPE returnValue;



  53.         if((*queue)->size > 0){//可以获取一个树结点

  54.                 returnValue = (*queue)->first->val;

  55.                 (*queue)->first = (*queue)->first->next;

  56.                 (*queue)->size--;

  57.         }

  58.         else{

  59.                 printf("\n已经空了.\n");

  60.         }



  61.         return returnValue;

  62. }
复制代码


main.c
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "huffman.c"
  4. #include "pQueue.c"

  5. typedef char ElemType;

  6. typedef struct BiTNode{
  7.         ElemType data;
  8.         int code;//权值
  9.         struct BiTNode *lchild, *rchild;
  10. } BiTNode, *BiTree;

  11. int main(void){
  12.         htTree *codeTree = buildTree("I 1ove FishC.com");//返回htree结点,指向霍夫曼树的根结点

  13.         hlTable *codeTable = buildTable(codeTree);//根据树生成各个字符的编码,存放在codeTable里面

  14.         encode(codeTable, "I love FishC.com!");//把字符变为codeTable中对应的编码,打印出来

  15.         decode(codeTree, "0011111000111");//解码;把编码变为codeTable中对应的字符

  16.         return 0;
  17. }
复制代码


huffman.h
  1. #pragma once

  2. #ifndef _HUFFMAN_H

  3. #define _HUFFMAN_H



  4. typedef struct _htNode {//树的结点

  5.         char symbol;

  6.         struct _htNode *left, *right;

  7. }htNode;



  8. typedef struct _htTree {//指向根结点

  9.         htNode *root;

  10. }htTree;



  11. typedef struct _hlNode {//编码

  12.         char symbol;//字符

  13.         char *code;//编码

  14.         struct _hlNode *next;

  15. }hlNode;



  16. typedef struct _hlTable {

  17.         hlNode *first;//指向第一个

  18.         hlNode *last;//指向最后一个

  19. }hlTable;



  20. htTree * buildTree(char *inputString);

  21. hlTable * buildTable(htTree *huffmanTree);

  22. void encode(hlTable *table, char *stringToEncode);

  23. void decode(htTree *tree, char *stringToDecode);



  24. #endif
复制代码


pQueue.h
  1. #pragma once//pragma once或者ifdef防止重定义冲突

  2. #ifndef _PQUEUE_H

  3. #define _PQUEUE_H



  4. #include "huffman.h"



  5. #define TYPE htNode *//htNode:树的结点



  6. #define MAX_SZ 256



  7. typedef struct _pQueueNode{

  8.         TYPE val;

  9.         unsigned int priority;//优先级;大于0

  10.         struct _pQueueNode *next;//指向下一个结点

  11. }pQueueNode;



  12. typedef struct _pQueue{

  13.         unsigned int size;

  14.         pQueueNode *first;

  15. }pQueue;



  16. void initPQueue(pQueue **queue);

  17. void addPQueue(pQueue **queue, TYPE val, unsigned int priority);

  18. TYPE getPQueue(pQueue **queue);



  19. #endif
复制代码

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-12-25 23:28:39 | 显示全部楼层
段错误,几个函数都检查了,找不到问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-12-27 11:24:09 | 显示全部楼层
SZMOD@8XJI[3]LI9GQXDJK4.png 御坂自己解决了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 06:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表