huffman树即Huffma编码的实现

自己写的Huffman树生成与Huffman编码实现 (实现了核心功能 ,打出了每个字符的huffman编码 其他的懒得实现了,有兴趣的朋友可以自己在我的基础增加功能 )

/* 原创文章 转载请附上原链接: https://www.cnblogs.com/jiujue/p/10325699.html  */

### 硬核警告 递归 玩的可以在往下看 核心是递归实现 ¥_¥  

上图:

上代码:(思路:通过递归将父亲的Huffman编码传给给孩子 孩子以此为基础进行在编码 )

1.头文件:(myHuffmanHead.h)

 1 #pragma once
 2 
 3 #pragma warning(disable :4996)
 4 #include<stdio.h>
 5 #include<stdlib.h>
 6 #include<string.h>
 7 
 8 /*
 9     huffmanTree : 思路
10      注:每个关键字为一个节点 整个数据使用链表存储
11         节点内容 : 关键字 ,出现次数 ,编码 , 下一个节点。 
12 
13         将 关键字的出现频率作为权值来生成HuffmanTree 然后进行Huffman code
14             //1.获取关键字频率 
15                 1.1 获取输入 并 记录 关键字 出现次数
16                                 
17             2.生成HuffmanTree
18                 
19                 
20             3.根据huffmanTree 进行HuffmanCode 并打印每个关键字的  Huffman编码 
21                     tips : 左 0 ; 右 1 
22 */
23 
24 typedef struct nodehuffmantree {
25 
26     char key;
27     int frequency;
28     
29     char *code;
30 
31     int isCoded;
32 
33     struct nodehuffmantree * next;
34     struct nodehuffmantree *lchild, *rchild;
35 
36 }nodeHuffmanTree_t;
37 
38 int myStrCat(char *des, char *str);
39 
40 int changeCode(char *strParent, char *strKid, char needAppend, char *tempspace);
41  
42 int linkCode(nodeHuffmanTree_t *headLinkList, char *input);
43 
44 int printLinkList(nodeHuffmanTree_t *head);
45 
46 int makeBranch(nodeHuffmanTree_t **spaceSave, int spaceSize, int t1, int t2);
47 
48 nodeHuffmanTree_t* isExitence(nodeHuffmanTree_t* head, char inputTemp);
49 
50 int creatHuffmanTree(nodeHuffmanTree_t *headLinkList, nodeHuffmanTree_t **headhuffmanTree);
51 
52 nodeHuffmanTree_t ** getSpaceSave(nodeHuffmanTree_t *headLinkList);
53 
54 int huffmanCode(nodeHuffmanTree_t *headLinkList, nodeHuffmanTree_t *headhuffmanTree);
View Code

 

2主函数入口:(source_1.c)

 1 #include"myHuffmanHead.h"
 2 
 3 
 4 int main()
 5 {
 6 
 7     nodeHuffmanTree_t *head = NULL;
 8     nodeHuffmanTree_t *headTree = NULL;
 9     char *needcode;
10     printf("please input : \n");
11 
12     obtainIput(&head, &needcode);
13 
14     creatHuffmanTree(head, &headTree);
15 
16     huffmanCode(head, headTree);
17 
18     printLinkList(head);
19 
20     //linkCode(head, needcode);
21 
22     system("pause");
23     return 0;
24 }
View Code

 

10.获取输入:(obtainIput.c)

 1 #include"myHuffmanHead.h"
 2 
 3 
 4 int obtainIput(nodeHuffmanTree_t **head,char **input)
 5 {
 6     char tempInput;
 7     nodeHuffmanTree_t **t1 = head;
 8     nodeHuffmanTree_t *t2 = NULL;
 9 
10     tempInput = getc(stdin);
11     *input = tempInput;
12     while (tempInput !='\n')
13     {
14         if (!(t2= isExitence( (*head), tempInput)))
15         {
16             nodeHuffmanTree_t *nodeTempHuffman = (nodeHuffmanTree_t *)malloc(sizeof(nodeHuffmanTree_t));
17 
18             (*t1) = nodeTempHuffman;
19 
20             nodeTempHuffman->key = tempInput;
21             nodeTempHuffman->frequency = 1;
22             nodeTempHuffman->next = NULL;
23             nodeTempHuffman->lchild = NULL;
24             nodeTempHuffman->rchild = NULL;
25             nodeTempHuffman->isCoded = 0;
26             t1 = &((*t1)->next);
27             tempInput = getc(stdin);
28         }
29         else
30         {
31             t2->frequency++ ;
32             tempInput = getc(stdin);
33             continue;
34         }
35     }
36     return 0;
37 }
View Code

 

3.创建一个Huffman树:(creatHuffmanTree.c)

 1 #include"myHuffmanHead.h"
 2 
 3 
 4 /*
 5     1.1 先遍历 链表 计算有几个需要编码
 6     1.2 创建一个空间 来存储 需要被编码的节点 并在每次编码后将编码后的过的删除 替换成 parent
 7 */
 8 
 9 static nodeHuffmanTree_t **spaceSave = NULL;
10 
11 
12 nodeHuffmanTree_t ** getSpaceSave(nodeHuffmanTree_t *headLinkList)
13 {
14     nodeHuffmanTree_t *t1 = headLinkList;
15 
16     int n = 0;
17     int i = 1;
18 
19     while (t1 != NULL)
20     {
21         n++;
22         t1 = t1->next;
23     }
24 
25     spaceSave = (nodeHuffmanTree_t*)malloc(sizeof(nodeHuffmanTree_t*)*n + 1);
26 
27     t1 = headLinkList;
28 
29     while (i < n + 1)
30     {
31         spaceSave[i] = t1;
32         ++i;
33         t1 = t1->next;
34     }
35 
36     (int)spaceSave[0] = n;
37 
38     return n;
39 }
40 
41 int creatHuffmanTree(nodeHuffmanTree_t *headLinkList, nodeHuffmanTree_t **headhuffmanTree)
42 {
43     //nodeHuffmanTree_t **spaceSave = NULL;
44 
45     int n = getSpaceSave(headLinkList);
46     int n2 = (int)spaceSave[0];
47 
48     while (n2 > 1)
49     {
50     
51         int t1, t2;
52 
53         getMinTwo(spaceSave, n, &t1, &t2);
54 
55 
56         makeBranch(spaceSave, n, t1, t2);
57 
58         n2--;
59     }
60 
61     while (n >= 1)
62     {
63         if (spaceSave[n] != NULL)
64         {
65             *headhuffmanTree = spaceSave[n];
66             break;
67         }
68         else
69         {
70             n--;
71         }
72     }
73 
74     return 0;
75 }
View Code

 

5.实现对huffman树的Huffman编码:

(huffmanCode.c)//先后顺序以代码为主 &_&

 1 #include"myHuffmanHead.h"
 2 
 3 
 4 
 5 /*
 6 
 7     递归 每次向下递归是 向左递归 传0 向右传1
 8     每次接受并改掉 '\0' 为传的 0或1 然后追加 '\0';
 9         每次传个n来记录编码空间长度 n+1
10 
11 */
12 int huffmanCode(nodeHuffmanTree_t *headLinkList, nodeHuffmanTree_t *headhuffmanTree)
13 {
14     headhuffmanTree->code = (char*)malloc(2);
15     
16     *(headhuffmanTree->code) = '\0';
17 
18     huffmanCode_(headhuffmanTree, headhuffmanTree->lchild, '0', 1);
19     huffmanCode_(headhuffmanTree, headhuffmanTree->rchild, '1', 1);
20 }
21 
22 int huffmanCode_(nodeHuffmanTree_t *parenthuffmanTree, nodeHuffmanTree_t *nexthuffmanTree, char tempCode, int layer)
23 {
24     if (NULL == nexthuffmanTree)
25     {
26         return 0;
27     }
28     else
29     {
30         char *tempSpace = (char*)malloc(sizeof(parenthuffmanTree->code));
31 
32         nexthuffmanTree->code = (char*)malloc(layer+2);
33         
34         changeCode(parenthuffmanTree->code, nexthuffmanTree->code, tempCode, tempSpace);
35 
36         huffmanCode_(nexthuffmanTree, nexthuffmanTree->lchild, '0', layer + 1);
37 
38         huffmanCode_(nexthuffmanTree, nexthuffmanTree->rchild, '1', layer + 1);
39 
40     }
41 }
View Code

 

  5.1.获取一个最小key的节点是个子功能:(getMinTwo.c)

 1 #include"myHuffmanHead.h"
 2 
 3 
 4 static int  flag = 0;
 5 
 6 int getMinTwo(nodeHuffmanTree_t **spaceSave,int spaceSize ,int *t1, int *t2)
 7 {
 8 
 9     int i = 0;
10     int j = 0;
11     
12     while (i<2)
13     {
14         int min = 1;
15         j = 0;
16 
17         while (j+1 < spaceSize)
18         {
19             if (NULL==spaceSave[1 + j])
20             {
21                 j++;
22                 continue;
23             }
24             if (0 == spaceSave[1 + j]->isCoded)
25             {
26                 min = 1 + j;
27                 break;
28             }
29             else
30             {
31                 j++;
32             }
33         }
34         
35         for (j= 0; j < spaceSize; ++j)
36         {
37             if (NULL == spaceSave[min] || NULL == spaceSave[1 + j])
38             {
39                 continue;
40             }
41             if (spaceSave[min]->frequency > spaceSave[1 + j]->frequency && spaceSave[1 + j]->isCoded !=1)
42             {
43                 min = 1 + j;
44             }
45         }
46 
47         spaceSave[min]->isCoded = 1;
48 
49         if (0 == flag)
50         {
51             *t1 = min;
52             flag++;
53         }
54         else
55         {
56             *t2 = min;
57             flag--;
58         }
59 
60         i++;
61     }
62 
63 
64 }
View Code

 

  5.2.判断是否已经编码:(isExitence.c)

 1 #include"myHuffmanHead.h"
 2 
 3 
 4 nodeHuffmanTree_t* isExitence(nodeHuffmanTree_t* head, char inputTemp)
 5 {
 6     int i = 0;
 7 
 8     if (NULL == head)
 9     {
10         return NULL;
11     }
12     else
13     {
14         
15 
16         if((head->key==inputTemp))
17         {
18             return head;
19         }
20         else
21         {
22             isExitence(head->next, inputTemp);
23         }
24     }
25 }
View Code

 

  5.3.创建分支:(makebranch.c)

 1 #include"myHuffmanHead.h"
 2 
 3 int makeBranch(nodeHuffmanTree_t **spaceSave, int spaceSize, int t1, int t2)
 4 {
 5 
 6     nodeHuffmanTree_t *newNode = (nodeHuffmanTree_t*)malloc(sizeof(nodeHuffmanTree_t));
 7 
 8     newNode->frequency = spaceSave[t1]->frequency + spaceSave[t2]->frequency;
 9     newNode->isCoded = 0;
10 
11     newNode->lchild = spaceSave[t1];
12     newNode->rchild = spaceSave[t2];
13 
14     spaceSave[t1] = newNode;
15     spaceSave[t2] = NULL;
16 
17 }
View Code

 

  5.4.实现拼接孩子的编码:(changeCode.c)

 1 #include"myHuffmanHead.h"
 2 
 3 
 4 int changeCode(char *strParent, char *strKid, char needAppend, char *tempspace)
 5 {
 6     strcpy(tempspace, strParent);
 7 
 8     char *tempP = tempspace;
 9     
10     while (1)
11     {
12         if (*tempP == '\0')
13         {
14             *tempP = needAppend;
15 
16             *(tempP + 1) = '\0';
17 
18             strcpy(strKid, tempspace);
19 
20             break;
21         }
22         else
23         {
24             ++tempP;
25         }
26     }
27     return 0;
28 }
View Code

 

  5.5.拼接Huffman编码:(myStrCat.c) 

 1 #include"myHuffmanHead.h"
 2 
 3 int myStrCat(char *des, char *str)
 4 {
 5     char *needCatP = des;
 6 
 7     while (1)
 8     {
 9         if (*needCatP == '\0')
10         {
11             *needCatP = str;
12 
13             *(needCatP + 1) = '\0';
14 
15             break;
16         }
17         else
18         {
19             ++needCatP;
20         }
21     }
22     return 0;
23 }
View Code

 

6.打印huffman编码:(printLinkList.c)

 1 #include"myHuffmanHead.h"
 2 
 3 int printLinkList(nodeHuffmanTree_t *head)
 4 {
 5     printf(" Key\t Frequncy\t HuffmanCode\n\n");
 6     while (head != NULL)
 7     {
 8         printf(" %c\t %d\t %s\n", head->key, head->frequency, head->code);
 9         
10         head = head->next;
11     }
12 }
View Code

 

结语:有问题欢迎提在下方 ,本人在校学生,时间较为充裕, 有时间会回复的。 

/* 原创文章 转载请附上原链接: https://www.cnblogs.com/jiujue/p/10325699.html  */

 

posted @ 2019-01-27 10:14  酒觉  阅读(879)  评论(0编辑  收藏  举报