自己写的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. layui动态设置checkbox选中状态

    今天在使用jquery动态设置layui的checkbox元素的选中状态时始终只能取消选中,却不能重新勾选,点击勾选则没有问题,代码如下 if (value == "true") ...

  2. 又拍云 API 使用的那些小事

    又拍云提供了丰富的 API 调用,为了减少用户在初次接入时可能会遇到的坑”,本文将对又拍云常用的 API 使用方法做个简单的梳理,力求让业务接入变得更简单,更高效. 目前我们的 API 主要有四大类, ...

  3. ReentrantLock 实现原理

    使用 synchronize 来做同步处理时,锁的获取和释放都是隐式的,实现的原理是通过编译后加上不同的机器指令来实现. 而 ReentrantLock 就是一个普通的类,它是基于 AQS(Abstr ...

  4. 『NOIP2018普及组题解』

    标题统计 题目描述 凯凯刚写了一篇美妙的作文,请问这篇作文的标题中有多少个字符? 注意:标题中可能包含大.小写英文字母.数字字符.空格和换行符.统计标题字 符数时,空格和换行符不计算在内. 输入格式 ...

  5. spring cloud + .net core实现微服务架构

    1.新建spring boot项目 2.添加spring-cloud-starter-eureka-server依赖(需提供版本信息) <!-- https://mvnrepository.co ...

  6. 使用ML.NET实现白葡萄酒品质预测

    导读:ML.NET系列文章 本文将基于ML.NET v0.2预览版,介绍机器学习中的分类和回归两个重要概念,并实现白葡萄酒品质预测. 本系列前面的文章也提到了一些,经典的机器学习最主要的特点就是模拟, ...

  7. DataRead和DataSet的异同

    第一种解释 DataReader和DataSet最大的区别在于,DataReader使用时始终占用SqlConnection(俗称:非断开式连接),在线操作数据库时,任何对SqlConnection的 ...

  8. web前端安全

    之前对web前端安全进行了总结,想给大家分享一下,有不对的地方,大家多多交流,由于写在了PPT上,只好给大家一张一张粘上来,希望大家不要在意,了解知识为主

  9. 阿里云ACE共创空间——MQ消息队列产品测试

    一.产品背景消息队列是阿里巴巴集团自主研发的专业消息中间件. 产品基于高可用分布式集群技术,提供消息订阅和发布.消息轨迹查询.定时(延时)消息.资源统计.监控报警等一系列消息云服务,是企业级互联网架构 ...

  10. [ Java面试题 ]框架篇二

    1.Hibernate工作原理及为什么要使用Hibernate? 工作原理: 1.读取并解析配置文件 2.读取并解析映射信息,创建SessionFactory 3.打开Session 4.创建事务Tr ...