zoukankan      html  css  js  c++  java
  • 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 : 
    ");
    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 !='
    ')
    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或1 然后追加 '';
     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) = '';
    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 == '')
    13         {
    14             *tempP = needAppend;
    15 
    16             *(tempP + 1) = '';
    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 == '')
    10         {
    11             *needCatP = str;
    12 
    13             *(needCatP + 1) = '';
    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	 Frequncy	 HuffmanCode
    
    ");
     6     while (head != NULL)
     7     {
     8         printf(" %c	 %d	 %s
    ", head->key, head->frequency, head->code);
     9         
    10         head = head->next;
    11     }
    12 }
    View Code

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

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

  • 相关阅读:
    如何设置SQL Server 全文搜索
    怎么样充分运用ASP.NET 2.0预编译
    怎么样用CSC.exe来编译Visual C#地代码文件
    ASP.NET设计中的性能优化问题
    给Repeater、Datalist和Datagrid增加自动编号列
    ASP.net的RUL重写
    正则表达式学习日记
    SQLCLR(三)触发器
    几个用常用的jscript验证
    Asp.net性能优化总结(二)
  • 原文地址:https://www.cnblogs.com/jiujue/p/10325699.html
Copyright © 2011-2022 走看看