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

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

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

上图:

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

1.头文件:(myHuffmanHead.h)

 #pragma once

 #pragma warning(disable :4996)
#include<stdio.h>
#include<stdlib.h>
#include<string.h> /*
huffmanTree : 思路
注:每个关键字为一个节点 整个数据使用链表存储
节点内容 : 关键字 ,出现次数 ,编码 , 下一个节点。 将 关键字的出现频率作为权值来生成HuffmanTree 然后进行Huffman code
//1.获取关键字频率
1.1 获取输入 并 记录 关键字 出现次数 2.生成HuffmanTree 3.根据huffmanTree 进行HuffmanCode 并打印每个关键字的 Huffman编码
tips : 左 0 ; 右 1
*/ typedef struct nodehuffmantree { char key;
int frequency; char *code; int isCoded; struct nodehuffmantree * next;
struct nodehuffmantree *lchild, *rchild; }nodeHuffmanTree_t; int myStrCat(char *des, char *str); int changeCode(char *strParent, char *strKid, char needAppend, char *tempspace); int linkCode(nodeHuffmanTree_t *headLinkList, char *input); int printLinkList(nodeHuffmanTree_t *head); int makeBranch(nodeHuffmanTree_t **spaceSave, int spaceSize, int t1, int t2); nodeHuffmanTree_t* isExitence(nodeHuffmanTree_t* head, char inputTemp); int creatHuffmanTree(nodeHuffmanTree_t *headLinkList, nodeHuffmanTree_t **headhuffmanTree); nodeHuffmanTree_t ** getSpaceSave(nodeHuffmanTree_t *headLinkList); int huffmanCode(nodeHuffmanTree_t *headLinkList, nodeHuffmanTree_t *headhuffmanTree);

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

 #include"myHuffmanHead.h"

 int main()
{ nodeHuffmanTree_t *head = NULL;
nodeHuffmanTree_t *headTree = NULL;
char *needcode;
printf("please input : \n"); obtainIput(&head, &needcode); creatHuffmanTree(head, &headTree); huffmanCode(head, headTree); printLinkList(head); //linkCode(head, needcode); system("pause");
return ;
}

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

 #include"myHuffmanHead.h"

 int obtainIput(nodeHuffmanTree_t **head,char **input)
{
char tempInput;
nodeHuffmanTree_t **t1 = head;
nodeHuffmanTree_t *t2 = NULL; tempInput = getc(stdin);
*input = tempInput;
while (tempInput !='\n')
{
if (!(t2= isExitence( (*head), tempInput)))
{
nodeHuffmanTree_t *nodeTempHuffman = (nodeHuffmanTree_t *)malloc(sizeof(nodeHuffmanTree_t)); (*t1) = nodeTempHuffman; nodeTempHuffman->key = tempInput;
nodeTempHuffman->frequency = ;
nodeTempHuffman->next = NULL;
nodeTempHuffman->lchild = NULL;
nodeTempHuffman->rchild = NULL;
nodeTempHuffman->isCoded = ;
t1 = &((*t1)->next);
tempInput = getc(stdin);
}
else
{
t2->frequency++ ;
tempInput = getc(stdin);
continue;
}
}
return ;
}

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

 #include"myHuffmanHead.h"

 /*
1.1 先遍历 链表 计算有几个需要编码
1.2 创建一个空间 来存储 需要被编码的节点 并在每次编码后将编码后的过的删除 替换成 parent
*/ static nodeHuffmanTree_t **spaceSave = NULL; nodeHuffmanTree_t ** getSpaceSave(nodeHuffmanTree_t *headLinkList)
{
nodeHuffmanTree_t *t1 = headLinkList; int n = ;
int i = ; while (t1 != NULL)
{
n++;
t1 = t1->next;
} spaceSave = (nodeHuffmanTree_t*)malloc(sizeof(nodeHuffmanTree_t*)*n + ); t1 = headLinkList; while (i < n + )
{
spaceSave[i] = t1;
++i;
t1 = t1->next;
} (int)spaceSave[] = n; return n;
} int creatHuffmanTree(nodeHuffmanTree_t *headLinkList, nodeHuffmanTree_t **headhuffmanTree)
{
//nodeHuffmanTree_t **spaceSave = NULL; int n = getSpaceSave(headLinkList);
int n2 = (int)spaceSave[]; while (n2 > )
{ int t1, t2; getMinTwo(spaceSave, n, &t1, &t2); makeBranch(spaceSave, n, t1, t2); n2--;
} while (n >= )
{
if (spaceSave[n] != NULL)
{
*headhuffmanTree = spaceSave[n];
break;
}
else
{
n--;
}
} return ;
}

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

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

 #include"myHuffmanHead.h"

 /*

     递归 每次向下递归是 向左递归 传0 向右传1
每次接受并改掉 '\0' 为传的 0或1 然后追加 '\0';
每次传个n来记录编码空间长度 n+1 */
int huffmanCode(nodeHuffmanTree_t *headLinkList, nodeHuffmanTree_t *headhuffmanTree)
{
headhuffmanTree->code = (char*)malloc(); *(headhuffmanTree->code) = '\0'; huffmanCode_(headhuffmanTree, headhuffmanTree->lchild, '', );
huffmanCode_(headhuffmanTree, headhuffmanTree->rchild, '', );
} int huffmanCode_(nodeHuffmanTree_t *parenthuffmanTree, nodeHuffmanTree_t *nexthuffmanTree, char tempCode, int layer)
{
if (NULL == nexthuffmanTree)
{
return ;
}
else
{
char *tempSpace = (char*)malloc(sizeof(parenthuffmanTree->code)); nexthuffmanTree->code = (char*)malloc(layer+); changeCode(parenthuffmanTree->code, nexthuffmanTree->code, tempCode, tempSpace); huffmanCode_(nexthuffmanTree, nexthuffmanTree->lchild, '', layer + ); huffmanCode_(nexthuffmanTree, nexthuffmanTree->rchild, '', layer + ); }
}

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

 #include"myHuffmanHead.h"

 static int  flag = ;

 int getMinTwo(nodeHuffmanTree_t **spaceSave,int spaceSize ,int *t1, int *t2)
{ int i = ;
int j = ; while (i<)
{
int min = ;
j = ; while (j+ < spaceSize)
{
if (NULL==spaceSave[ + j])
{
j++;
continue;
}
if ( == spaceSave[ + j]->isCoded)
{
min = + j;
break;
}
else
{
j++;
}
} for (j= ; j < spaceSize; ++j)
{
if (NULL == spaceSave[min] || NULL == spaceSave[ + j])
{
continue;
}
if (spaceSave[min]->frequency > spaceSave[ + j]->frequency && spaceSave[ + j]->isCoded !=)
{
min = + j;
}
} spaceSave[min]->isCoded = ; if ( == flag)
{
*t1 = min;
flag++;
}
else
{
*t2 = min;
flag--;
} i++;
} }

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

 #include"myHuffmanHead.h"

 nodeHuffmanTree_t* isExitence(nodeHuffmanTree_t* head, char inputTemp)
{
int i = ; if (NULL == head)
{
return NULL;
}
else
{ if((head->key==inputTemp))
{
return head;
}
else
{
isExitence(head->next, inputTemp);
}
}
}

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

 #include"myHuffmanHead.h"

 int makeBranch(nodeHuffmanTree_t **spaceSave, int spaceSize, int t1, int t2)
{ nodeHuffmanTree_t *newNode = (nodeHuffmanTree_t*)malloc(sizeof(nodeHuffmanTree_t)); newNode->frequency = spaceSave[t1]->frequency + spaceSave[t2]->frequency;
newNode->isCoded = ; newNode->lchild = spaceSave[t1];
newNode->rchild = spaceSave[t2]; spaceSave[t1] = newNode;
spaceSave[t2] = NULL; }

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

 #include"myHuffmanHead.h"

 int changeCode(char *strParent, char *strKid, char needAppend, char *tempspace)
{
strcpy(tempspace, strParent); char *tempP = tempspace; while ()
{
if (*tempP == '\0')
{
*tempP = needAppend; *(tempP + ) = '\0'; strcpy(strKid, tempspace); break;
}
else
{
++tempP;
}
}
return ;
}

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

 #include"myHuffmanHead.h"

 int myStrCat(char *des, char *str)
{
char *needCatP = des; while ()
{
if (*needCatP == '\0')
{
*needCatP = str; *(needCatP + ) = '\0'; break;
}
else
{
++needCatP;
}
}
return ;
}

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

 #include"myHuffmanHead.h"

 int printLinkList(nodeHuffmanTree_t *head)
{
printf(" Key\t Frequncy\t HuffmanCode\n\n");
while (head != NULL)
{
printf(" %c\t %d\t %s\n", head->key, head->frequency, head->code); head = head->next;
}
}

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

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

huffman树即Huffma编码的实现的更多相关文章

  1. Huffman树的编码译码

    上个学期做的课程设计,关于Huffman树的编码译码. 要求: 输入Huffman树各个叶结点的字符和权值,建立Huffman树并执行编码操作 输入一行仅由01组成的电文字符串,根据建立的Huffma ...

  2. Huffman树的构造及编码与译码的实现

    哈夫曼树介绍 哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树.所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数) ...

  3. Huffman树及其编解码

    Huffman树--编解码 介绍:   Huffman树可以根据输入的字符串中某个字符出现的次数来给某个字符设定一个权值,然后可以根据权值的大小给一个给定的字符串编码,或者对一串编码进行解码,可以用于 ...

  4. [数据结构与算法]哈夫曼(Huffman)树与哈夫曼编码

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  5. 哈夫曼(Huffman)树和哈夫曼编码

    一.哈夫曼(Huffman)树和哈夫曼编码 1.哈夫曼树(Huffman)又称最优二叉树,是一类带权路径长度最短的树, 常用于信息检测. 定义: 结点间的路径长度:树中一个结点到另一个结点之间分支数目 ...

  6. Huffman树与编码

    带权路径最小的二叉树称为最优二叉树或Huffman(哈夫曼树). Huffman树的构造 将节点的权值存入数组中,由数组开始构造Huffman树.初始化指针数组,指针指向含有权值的孤立节点. b = ...

  7. Huffman编码(Huffman树)

    [0]README 0.1) 本文总结于 数据结构与算法分析, 源代码均为原创, 旨在 理解 "Huffman编码(Huffman树)" 的idea 并用源代码加以实现: 0.2) ...

  8. 数据结构(二十七)Huffman树和Huffman编码

    Huffman树是一种在编码技术方面得到广泛应用的二叉树,它也是一种最优二叉树. 一.霍夫曼树的基本概念 1.结点的路径和结点的路径长度:结点间的路径是指从一个结点到另一个结点所经历的结点和分支序列. ...

  9. Huffman树与Huffman编码

    1.Huffman树 今天复习Huffman树.依稀记得自己被Huffman树虐的经历.还记得是7月份,我刚开始看数据结构与算法,根本看不懂Huffman树的操作.后来我终于悟出了Huffman树是怎 ...

随机推荐

  1. [Swift]LeetCode877. 石子游戏 | Stone Game

    Alex and Lee play a game with piles of stones.  There are an even number of piles arranged in a row, ...

  2. 老司机教你用原生JDK 撸一个 MVC 框架!!!

    其实 Spring MVC 是一个基于请求驱动的 Web 框架,并且也使用了前端控制器模式来进行设计,再根据请求映射规则分发给相应的页面控制器进行处理,具体工作原理见下图. 在这里,就不详细谈相关的原 ...

  3. Spring Data Jpa接口简介

    Repository接口 public interface Repository<T, ID> {....} 提供了按方法名称的查询方式: 提供了@Query的查询方式 可能遇到的错误: ...

  4. 重磅推出TabLayout高级窗口组件

    TabLayout是在APICloud现有窗口系统基础上升级而来的高级窗口组件,符合Material Design规范,可通过简单的配置为窗口实现原生的导航栏和TabBar,它将帮助您节省30%以上的 ...

  5. 华为oj之质数因子

    题目: 质数因子 热度指数:5143 时间限制:1秒 空间限制:32768K 本题知识点: 排序 题目描述 功能:输入一个正整数,按照从小到大的顺序输出它的所有质数的因子(如180的质数因子为2 2 ...

  6. arrays.xml中使用integer-array引用drawable图片资源,代码中如何将这些图片资源赋值到ImageView控件中

    当我们在arrays.xml文件中声明一些图片资源数组的时候: <?xml version="1.0" encoding="utf-8"?> < ...

  7. shell实战之tomcat看门狗

    1.脚本简介 tomcat看门狗,在tomcat进程异常退出时会自动拉起tomcat进程并记录tomcat运行的日志. 函数说明: log_info:打印日志的函数,入参为需要在日志中打印的msg s ...

  8. Spring系列(七) Spring MVC 异常处理

    Servlet传统异常处理 Servlet规范规定了当web应用发生异常时必须能够指明, 并确定了该如何处理, 规定了错误信息应该包含的内容和展示页面的方式.(详细可以参考servlet规范文档) 处 ...

  9. Spring Boot分布式系统实践【2】-框架搭建

    前言 技术选型已经做完,那就来搭建框架了. 首先基于mvc思想,设计这套框架也是基于此,也会设计Dao层.Service层.Controller层.视图层等,同时也要考虑到dubbo的调用原理.   ...

  10. Tomcat多实例部署

    前言 以前总是采用很Low的方式太同一台服务器上部署多个Web应用,步骤是这样的:Copy Tomcat目录-->更改conf/server.xml三个端口号----->部署war包--- ...