huffman编码
来源:互联网 发布:手机制作视频的软件 编辑:程序博客网 时间:2024/04/27 08:43
总所周知huffman编码能有效的减小码长,其实现的思想如下:
首先找出最小的两个数,求其和值为另一个数,插入到原数中,之后再从数中找出最小的两个,依次类推,直到最后一个数的概论为一结束。
我是用链表实现的,首先把所有的数存放到一个链表里面,从小到大的排序(用一个排序函数实现),之后去头结点和下一个节点合并为一个新的节点,查到链表的头部,两个节点分别为其左右孩子,左边的编码为0,右边的编码为1,同时将它们从链表中删除,这样有用排序函数排序一下链表,重复上面的操作直到链表只有一个节点,也即该节点的概率为1(我是用这个来判断是否结束建树的,以及遍历树的),这样就生成了一颗huffman树,之后就是遍历huffman树,打印编码,最后是销毁整棵huffman树。
源代码如下:
/* * This code has a disadvantage that you should change the NodeNum * when you use another probability sets * In this code NodeNum = 3 means there are 4 nodes! * But I will try to solve this problem!*/#include <stdio.h>#include <stdlib.h>#define LEN sizeof(struct HuffNode)#define NodeNum 3struct HuffNode{ float gailv; int code; struct HuffNode *Next; struct HuffNode *Parent; struct HuffNode *Lchild; struct HuffNode *Rchild; };struct HuffNode *creatLink(){ struct HuffNode *head, *TempNode1, *TempNode2; int flag = NodeNum; float NodeGailv = 0.0; printf("Please input %d gailv and the total of their proority should be 1.0!\n\n", NodeNum+1); TempNode1 = (struct HuffNode *) malloc(LEN); TempNode1->code = 0; TempNode1->Parent = NULL; TempNode1->Lchild = NULL; TempNode1->Rchild =NULL; TempNode1->Next =NULL; head = TempNode1; printf("please input the priority:\n"); scanf("%f", &TempNode1->gailv); NodeGailv = NodeGailv + TempNode1->gailv; TempNode1->code = 0; TempNode2 = TempNode1; while(flag) { TempNode1 = (struct HuffNode *) malloc(LEN); TempNode2->Next = TempNode1; printf("please input the prabobility:\n"); scanf("%f", &TempNode1->gailv); TempNode1->code = 0; TempNode1->Parent = NULL; TempNode1->Lchild = NULL; TempNode1->Rchild = NULL; TempNode1->Next = NULL; flag--; TempNode2 = TempNode1; NodeGailv = NodeGailv + TempNode1->gailv; //printf(" gailv is %f\n", NodeGailv); } TempNode2->Next = NULL; if(NodeGailv == 1.0) { return head; } else { printf("Gailv is not 1.0, you input the wrong priorities!\n"); return NULL; }}void printLink(struct HuffNode *head){ struct HuffNode *HuffHead = head; while(HuffHead != NULL) { printf("The prabobility is : %7.4f and the code is :%d\n", HuffHead->gailv, HuffHead->code); HuffHead = HuffHead->Next; } }void swapNode(struct HuffNode *node1, struct HuffNode *node2){ struct HuffNode *temp = (struct HuffNode *)malloc(LEN); temp->code = node1->code; temp->gailv = node1->gailv; temp->Parent = node1->Parent; temp->Lchild = node1->Lchild; temp->Rchild = node1->Rchild; //temp->Next = node1->Next; node1->code = node2->code; node1->gailv = node2->gailv; node1->Parent = node2->Parent; node1->Lchild = node2->Lchild; node1->Rchild = node2->Rchild; // node1->Next = node2->Next; node2->code = temp->code; node2->gailv = temp->gailv; node2->Parent = temp->Parent; node2->Lchild = temp->Lchild; node2->Rchild = temp->Rchild; //node2->Next = temp->Next;}void sortLink(struct HuffNode *head){ struct HuffNode *HuffHead = head,*Head = head, *temp; int flag = NodeNum; while(flag) { while(HuffHead != NULL) { temp = HuffHead; if(temp->Next !=NULL) { if((temp->gailv) > (temp->Next->gailv)) { swapNode(temp, temp->Next); } } HuffHead = HuffHead->Next; } HuffHead = head; flag--; }}struct HuffNode *creatTree(struct HuffNode *head){ struct HuffNode *HuffHead = head, *temp; int flag = NodeNum; while(flag) { temp = HuffHead; struct HuffNode *NewNode = (struct HuffNode *) malloc(LEN); NewNode->Next = temp; NewNode->code = 0; NewNode->gailv = temp->gailv + temp->Next->gailv; NewNode->Lchild = temp; NewNode->Lchild->Parent = NewNode; NewNode->Rchild = temp->Next; NewNode->Rchild->Parent = NewNode; temp->Next->code = 1; NewNode->Next = temp->Next->Next; temp->Next->Next= NULL; temp->Next = NULL; //printf("The prabobility is : %7.4f and the code is :%d\n", NewNode->gailv, NewNode->code); //printf("The prabobility of Lchild is : %7.4f and the code is :%d\n", NewNode->Lchild->gailv, NewNode->Lchild->code); //printf("The prabobility of Rchild is : %7.4f and the code is :%d\n", NewNode->Rchild->gailv, NewNode->Rchild->code); HuffHead = NewNode; sortLink(HuffHead); flag--; } printf("\nCreat HuffTree Succeed!\n"); head = HuffHead; return head;}void printTree(struct HuffNode *head){ struct HuffNode *HuffHead = head; if(HuffHead != NULL) { printf("gailv: %7.4f code: %d\n", HuffHead->gailv, HuffHead->code); printTree(HuffHead->Lchild); printTree(HuffHead->Rchild); }}void printCode(struct HuffNode *leaf) { struct HuffNode *HuffHead = leaf; int a[NodeNum] = {0}, i = 0, j=0; printf("gailv: %7.4f code:", HuffHead->gailv); //printf(" the parent of %7.4f is %7.4f Huffcode:", HuffHead->gailv, HuffHead->Parent->gailv); while(HuffHead->gailv != 1.0) { a[i++] = HuffHead->code; HuffHead = HuffHead->Parent; } for(j=i-1; j>=0; j--) { printf("%d ", a[j]); } /* while(HuffHead ->gailv != 10) { printf("%d ", HuffHead->code); HuffHead = HuffHead->Parent; }*/ printf("\n");}void printHuffCode(struct HuffNode *head) //打印的思路是这样的,首先从 根节点遍历到叶子节点,,之后再从叶子节点遍历回根节点, { //把编码存在一个数组中,再打印这个数组,即 printCode(的功能) struct HuffNode *HuffHead = head; if(HuffHead != NULL) { if(HuffHead->Lchild == NULL) { //printf("gailv: %7.4f code: %d\n", HuffHead->gailv, HuffHead->code); printCode(HuffHead); printf("\n"); } printHuffCode(HuffHead->Lchild); printHuffCode(HuffHead->Rchild); } }void destroy(struct HuffNode **head){ if(*head != NULL) { destroy(&(*head)->Lchild); destroy(&(*head)->Rchild); // printf(" before free gailv is %f !", (*head)->gailv); free(*head); // printf(" Free Succeed!\n"); *head = NULL; }}int main(){ struct HuffNode *head, *HuffHead; printf("\n^-^ Welcome come to Huffman Code\n\n"); head = creatLink(); if(head == NULL) { system("pause"); return 1; } printf("\nThe original link is:\n"); printLink(head); HuffHead = head; sortLink(head); printf("\nThe sort link is:\n"); printLink(head); printf("\n\n"); head = creatTree(head); //printf("gailv: %7.4f code: %d\n", head->gailv, head->code); printTree(head); printf("\n\n"); printf("The Huffcode is: \n"); printHuffCode(head); /* while(head->Parent != NULL) { freeTree(head); }*/ destroy(&head); system("pause"); return 0; }
运行截图如下:
- Huffman树&&Huffman编码
- huffman编码
- huffman编码
- HUFFMAN 编码
- Huffman编码
- huffman编码
- huffman编码
- Huffman编码
- Huffman编码
- Huffman编码
- Huffman编码
- HuffMan编码
- Huffman编码
- Huffman编码
- Huffman编码
- huffman编码
- Huffman编码
- huffman编码
- 四、数组(二)
- 三、字符串(一)
- EasyMock 使用方法与原理剖析
- 三、字符串(二)
- 【译】使用Android NDK的系统和软件需求(System and SoftwareRequirements)
- huffman编码
- android应用程序完全退出方法
- Intent传递一个Bean
- C语言中栈的使用
- MockObject的好处:
- 二、函数
- MockMe:一个新的JavaScript mocking框架
- 根据IP获取省市
- 使用 DEF (模块定义) 文件从 DLL 导出函数和类