huffman树即Huffma编码的实现
自己写的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编码的实现的更多相关文章
- Huffman树的编码译码
上个学期做的课程设计,关于Huffman树的编码译码. 要求: 输入Huffman树各个叶结点的字符和权值,建立Huffman树并执行编码操作 输入一行仅由01组成的电文字符串,根据建立的Huffma ...
- Huffman树的构造及编码与译码的实现
哈夫曼树介绍 哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树.所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数) ...
- Huffman树及其编解码
Huffman树--编解码 介绍: Huffman树可以根据输入的字符串中某个字符出现的次数来给某个字符设定一个权值,然后可以根据权值的大小给一个给定的字符串编码,或者对一串编码进行解码,可以用于 ...
- [数据结构与算法]哈夫曼(Huffman)树与哈夫曼编码
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- 哈夫曼(Huffman)树和哈夫曼编码
一.哈夫曼(Huffman)树和哈夫曼编码 1.哈夫曼树(Huffman)又称最优二叉树,是一类带权路径长度最短的树, 常用于信息检测. 定义: 结点间的路径长度:树中一个结点到另一个结点之间分支数目 ...
- Huffman树与编码
带权路径最小的二叉树称为最优二叉树或Huffman(哈夫曼树). Huffman树的构造 将节点的权值存入数组中,由数组开始构造Huffman树.初始化指针数组,指针指向含有权值的孤立节点. b = ...
- Huffman编码(Huffman树)
[0]README 0.1) 本文总结于 数据结构与算法分析, 源代码均为原创, 旨在 理解 "Huffman编码(Huffman树)" 的idea 并用源代码加以实现: 0.2) ...
- 数据结构(二十七)Huffman树和Huffman编码
Huffman树是一种在编码技术方面得到广泛应用的二叉树,它也是一种最优二叉树. 一.霍夫曼树的基本概念 1.结点的路径和结点的路径长度:结点间的路径是指从一个结点到另一个结点所经历的结点和分支序列. ...
- Huffman树与Huffman编码
1.Huffman树 今天复习Huffman树.依稀记得自己被Huffman树虐的经历.还记得是7月份,我刚开始看数据结构与算法,根本看不懂Huffman树的操作.后来我终于悟出了Huffman树是怎 ...
随机推荐
- [Swift]LeetCode816. 模糊坐标 | Ambiguous Coordinates
We had some 2-dimensional coordinates, like "(1, 3)" or "(2, 0.5)". Then, we re ...
- Linux 文件夹压缩命令总结
tar命令 解包:tar zxvf FileName.tar 打包:tar czvf FileName.tar DirName gz命令 解压1:gunzip FileName.gz 解压2:gzip ...
- 看完Andoird9.0 Pie的隐藏特性,我买了SSL证书
今年 8 月,Google 正式公布了 Android 9.0 ,新的甜点名称也正式揭晓——Pie.这次的大版本升级中,藏着一个不起眼的特性:默认使用 HTTPS 为了将所有网络流量从明文(未加密的 ...
- 一个.NET Core开发者的Linux入门学习笔记
用.NET Core开发也有一段时间了,但是由于工作原因一直都是在Windows系统上进行的开发,一直想学习Linux然后把.NET Core开发的程序跑在Linux上,然后把心得体会记录一下发布再博 ...
- Config ConnectionStrings
<connectionStrings> <add name ="MyschoolConnectionString" connectionString =" ...
- 关于QT下资源使用和资源占用…
原文地址:关于QT下资源使用和资源占用内存过多的问题作者:技术成就梦想 最近研究了一下如何从外部动态调用图片的问题,从而研究了图片资源的使用方法.网上最常见的帖子是这个,感觉总结的还不错. h ...
- RabbitMQ学习笔记(四) Routing
新的场景 在我们学习了RabbitMQ的发布与订阅之后,我们很容易就可以完成一个简单的消息群发器. 使用这个消息群发器,所有的消费者程序实例都会接收到相同的消息信息,从而实现广播的效果. 但是这种广播 ...
- Java设计模式学习总结
设计模式基础学习总结 这篇总结主要是基于我之前设计模式基础系列文章而形成的的.主要是把重要的知识点用自己的话说了一遍,可能会有一些错误,还望见谅和指点.谢谢 更多详细内容可以查看我的专栏文章:设计模式 ...
- Chapter 5 Blood Type——4
"Does he mean you?" Jessica asked with insulting astonishment in her voice. “他对你有意思吗?”Jess ...
- 我们知道CDN护航了双11十年,却不知道背后有那么多故事……
情不知如何而起,竟一往情深.恰如我们.十年前,因为相信,所以看见.十年后,就在眼前,看见一切. 当2018天猫双11成交额2135亿元的大屏上,打出这么一段字的时候,参与双11护航的阿里云CDN技术掌 ...