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]LeetCode848. 字母移位 | Shifting Letters
We have a string S of lowercase letters, and an integer array shifts. Call the shift of a letter, th ...
- 基于ipv6的数据抓包
一.实验拓扑 二.配置过程 以r1为例 R1: R1(config)#int f0/0 R1(config-if)#ipv6 enable R1(config-if)#ipv6 address 200 ...
- mysql主从集群配置
1.二进制日志 主: #master vim /etc/mysql/my.cnf #server-id server-id=2 #二进制日志 log-bin=musql-bin#statement r ...
- java程序员的NodeJS初识篇
摘要 作为一个一直用java来写后端的程序员用NodeJS来写后台,实在不是很爽.这里记下这两个月的NodeJS学习所遇之坑,与java转NodeJS的同仁共勉.学习时间不长,若有理解错误,望指正. ...
- Java9发布回顾Java 8的十大新特性
java9已经在北京时间9月22日正式发布,开发者可以在oracle jdk官网上下载到最新的jdk9. 今天,我们先来一起复习一下2014年发布的Java 8的十大新特性.先来喝杯java~~~ 按 ...
- Dubbo(一) —— 基础知识和项目搭建
一.分布式基础理论 1.什么是分布式系统? <分布式系统原理与范型>定义: “分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统” 分布式系统(distribut ...
- Java开发知识之Java的数字处理类Math类
Java开发知识之Java的数字处理类Math类 一丶Java.text.DecimalFormat类与NumberFormat类 首先 Java.text.DecimalFormat指的是Decim ...
- ubuntu 15.10 设置静态ip 分配固定ip 设置dns 设置网关 命令行配置ip 固定ip不生效怎么办
要用到的文件: 配置接口信息 /etc/network/interfaces 配置内容: auto eth0 iface eth0 inet static address 192.168.216.18 ...
- 流式大数据计算实践(5)----HBase使用&SpringBoot集成
一.前言 1.上文中我们搭建好了一套HBase集群环境,这一文我们学习一下HBase的基本操作和客户端API的使用 二.shell操作 先通过命令进入HBase的命令行操作 /work/soft/hb ...
- Joda-Time开源库
Joda-Time是一个面向 Java™ 平台的易于使用的开源时间日期库. 依赖 <dependency> <groupId>joda-time</groupId> ...