自己写的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]LeetCode693. 交替位二进制数 | Binary Number with Alternating Bits

    Given a positive integer, check whether it has alternating bits: namely, if two adjacent bits will a ...

  2. [Swift]LeetCode754. 到达终点数字 | Reach a Number

    You are standing at position 0 on an infinite number line. There is a goal at position target. On ea ...

  3. [Swift]LeetCode928. 尽量减少恶意软件的传播 II | Minimize Malware Spread II

    (This problem is the same as Minimize Malware Spread, with the differences bolded.) In a network of ...

  4. websocket+rabbitmq实战

    1. websocket+rabbitmq实战 1.1. 前言   接到的需求是后台定向给指定web登录用户推送消息,且可能同一账号会登录多个客户端都要接收到消息 1.2. 遇坑 基于springbo ...

  5. ElasticSearch(2)---SpringBoot整合ElasticSearch

    SpringBoot整合ElasticSearch 一.基于spring-boot-starter-data-elasticsearch整合 开发环境:springboot版本:2.0.1,elast ...

  6. Kafka分区与消费者的关系

    1.  前言 我们知道,生产者发送消息到主题,消费者订阅主题(以消费者组的名义订阅),而主题下是分区,消息是存储在分区中的,所以事实上生产者发送消息到分区,消费者则从分区读取消息,那么,这里问题来了, ...

  7. java基础(五)-----关键字static

    在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个“伪全局”的概念,在Java中static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,当然也可以修饰代码块. ...

  8. 前端笔记之JavaScript(一)初识JavaScript

    一.JavaScript简介 1.1网页分层 web前端一共分三层: 结构层 HTML         : 负责搭建页面结构 样式层 CSS          : 负责页面的美观 行为层 JavaSc ...

  9. 决策树 Decision Tree

    决策树是一个类似于流程图的树结构:其中,每个内部结点表示在一个属性上的测试,每个分支代表一个属性输出,而每个树叶结点代表类或类分布.树的最顶层是根结点.  决策树的构建 想要构建一个决策树,那么咱们 ...

  10. 【Java基础】【22IO(其他流)&Properties】

    22.01_IO流(序列流)(了解) 1.什么是序列流 序列流可以把多个字节输入流整合成一个, 从序列流中读取数据时, 将从被整合的第一个流开始读, 读完一个之后继续读第二个, 以此类推. 2.使用方 ...