博客
关于我
哈弗曼编码
阅读量:364 次
发布时间:2019-03-04

本文共 4613 字,大约阅读时间需要 15 分钟。

数据压缩中的编码问题实验

定义相关结构体和常量

#define _CRT_SECURE_NO_WARNINGS#include 
#include
#define Minweight -1typedef struct Node* ElementType;struct Node { int Weight; char Key;};typedef struct HfTNode* HuffmanTree;struct HfTNode { ElementType Data; HuffmanTree Left, Right;};typedef struct Heapstruct* MinHeap;struct Heapstruct { HuffmanTree* Elements; int Size; int Capacity;};typedef struct SNode* PtrToSNode;struct SNode { ElementType Data; PtrToSNode Next;};typedef PtrToSNode Stack;Stack CreateStack(void);int IsEmpty_Stack(Stack);void Push(Stack, ElementType);ElementType Pop(Stack);ElementType GetStackTop(Stack);

创建堆结构

MinHeap CreateMinHeap(int MaxSize) {    MinHeap H;    H = (MinHeap)malloc(sizeof(struct Heapstruct));    H->Elements = (HuffmanTree*)malloc(sizeof(HuffmanTree) * (MaxSize + 1));    H->Size = MaxSize;    H->Capacity = MaxSize;        // 初始化第一个元素    H->Elements[0] = (HuffmanTree)malloc(sizeof(struct HfTNode));    H->Elements[0]->Data = (ElementType)malloc(sizeof(struct Node));    H->Elements[0]->Data->Weight = Minweight;        return H;}

堆操作函数

int IsEmpty_MinHeap(MinHeap H) {    return H->Size == 0;}int IsFull_MinHeap(MinHeap H) {    return H->Size == H->Capacity;}void Insert_MinHeap(MinHeap H, HuffmanTree Item) {    int i;    if (IsFull_MinHeap(H)) return;        i = ++H->Size; // i相当于子结点下标,i/2相当于父结点下标    for (; H->Elements[i / 2]->Data->Weight > Item->Data->Weight; i /= 2) {        H->Elements[i] = H->Elements[i / 2];    }    H->Elements[i] = Item;}

删除堆中的最小元素

HuffmanTree Delete_MinHeap(MinHeap H) {    HuffmanTree Item, MinItem;    int Parent, Child;        if (IsEmpty_MinHeap(H)) return NULL;        MinItem = H->Elements[1];    Item = H->Elements[H->Size--];        for (Parent = 1; Parent * 2 <= H->Size; Parent = Child) {        Child = Parent * 2;        if (H->Elements[Child]->Data->Weight > H->Elements[Child + 1]->Data->Weight)            Child++;                if (H->Elements[Child]->Data->Weight > Item->Data->Weight)            break;        else            H->Elements[Parent] = H->Elements[Child];    }    H->Elements[Parent] = Item;        return MinItem;}

哈弗曼编码的构建过程

void MinMaking(MinHeap H, int Root) {    int Parent, Child;    HuffmanTree Item;        Item = H->Elements[Root];    for (Parent = Root; Parent * 2 <= H->Size; Parent = Child) {        Child = Parent * 2;        if (Child + 1 < H->Size && H->Elements[Child]->Data->Weight > H->Elements[Child + 1]->Data->Weight)            Child++;                if (H->Elements[Child]->Data->Weight > Item->Data->Weight)            break;        else            H->Elements[Parent] = H->Elements[Child];    }    H->Elements[Parent] = Item;}

主函数实现

int main() {    Stack S;    int MaxSize;        HuffmanTree T;    S = CreateStack();        do {        printf("输入关键字个数\n");        scanf("%d", &MaxSize);        getchar();        if (MaxSize <= 1) {            printf("不必为%d个关键字编码\n", MaxSize);        } else            break;    } while (1);        MinHeap H = CreateMinHeap(MaxSize);        for (int i = 1; i <= MaxSize; i++) {        H->Elements[i] = (HuffmanTree)malloc(sizeof(struct HfTNode));        H->Elements[i]->Left = NULL;        H->Elements[i]->Right = NULL;        H->Elements[i]->Data = (ElementType)malloc(sizeof(struct Node));                printf("输入关键字及出现频率\n");        scanf("%c %d", &H->Elements[i]->Data->Key, &H->Elements[i]->Data->Weight);        getchar();    }        T = Huffman(H);        // 打印哈弗曼树的编码    PrintPath(T);}

哈弗曼树编码生成函数

void PrintPath(HuffmanTree T) {    HuffmanTree PtoT;    HuffmanTree Root;    char Word[10];    int i = 0;        while (T->Data->Key != -1) {        PtoT = T;        Root = PtoT;        i = 0;                while (1) {            if (!PtoT->Left && !PtoT->Right) {                Word[i++] = PtoT->Data->Key;                Word[i] = '\0';                printf("%s\n", Word);                PtoT->Data->Key = -1;                                if ((!Root->Left || Root->Left->Data->Key == -1) &&                    (!Root->Right || Root->Right->Data->Key == -1))                    Root->Data->Key = -1;                                break;            } else if (PtoT->Left && PtoT->Left->Data->Key != -1) {                Word[i++] = '1';                Root = PtoT;                PtoT = PtoT->Left;                continue;            } else if (PtoT->Right && PtoT->Right->Data->Key != -1) {                Word[i++] = '0';                Root = PtoT;                PtoT = PtoT->Right;                continue;            }                        PtoT->Data->Key = -1;            break;        }    }}

转载地址:http://ivbr.baihongyu.com/

你可能感兴趣的文章
Python 使用flush函数将缓冲区数据立即写磁盘
查看>>
python 使用in判断不准确,in不好使
查看>>
Python 使用pandas 进行查询和统计详解
查看>>
Redis 配置文件redis.conf详细解释
查看>>
python网络爬虫(2)——scrapy框架的基础使用
查看>>
python网络爬虫实例教程试读_Python网络爬虫实战教程(全套完整版) - 学途无忧网 - 做技术的王者 - Powered By EduSoho...
查看>>
Python 使用哈希函数用于加密
查看>>
Python 依赖管理的革新——Poetry 深度解析
查看>>
python 保留精度及增加去除数字的千位分隔符(金额化数字)
查看>>
python 倒计时 9,8,7,。。。。。。0
查看>>
Python 入门开发学习笔记之数据的增删改查
查看>>
Python 入门教程(2)搭建环境 2.4、VSCode配置Node.js运行环境
查看>>
Python 八大排序算法合集
查看>>
python 关于epoll的学习
查看>>
Python 内存管理
查看>>
Python 内嵌函数:它们有什么用处?
查看>>
Python 内置 sum 函数 vs. for 循环性能
查看>>
python 内置slice的用法
查看>>
Python 内置时间模块
查看>>
python 内部如何实现命名元组?
查看>>