数据结构与C语言实现(五)——树(下):哈夫曼树与哈夫曼编码

来源:互联网 发布:java工程师所属部门 编辑:程序博客网 时间:2024/06/06 07:27
/*哈弗曼树的定义带权路径长度:设二叉树有n个叶子节点,每个叶子节点带有权值Wk,从根节点到每个椰子节点的长度为Lk则每个叶子节点的带权路径的长度之和就是每个wk*lk之后加起来最优二叉树或者哈夫曼树:WPL最小的二叉树*/#include <stdio.h>#include <stdlib.h>//哈弗曼树的构造——每次把权值最小的两个树合并#define MAXSIZE 100typedef struct TreeNode* HuffmanTree;struct TreeNode{int Weight;HuffmanTree left, right;};struct HeapNode{HuffmanTree data[MAXSIZE];int size;int MaxSize;};typedef struct HeapNode* MinHeap;//堆的实现,建立最小堆void BuildMinHeap(MinHeap H){int parent, child, temp;int i;H->data[0]->Weight = -1;//哨兵for (i = H->size / 2; i > 0; i--)//从深度倒数第二的位置从后向前走{temp = H->data[i]->Weight;for (parent = i; parent * 2 <= H->size; parent = child){//下面寻找最小的儿子child = parent * 2;//找到爸爸节点的儿子if ((child != H->size) && (H->data[child + 1]->Weight < H->data[child]->Weight))child++;//如果说右儿子比左儿子要小,那么左儿子胜出。因为我们这里建立的是最小堆。//下面进行替换if (temp <= H->data[child]->Weight) break;else{H->data[parent]->Weight = H->data[child]->Weight;}}H->data[parent]->Weight = temp;}}//堆的删除最小值操作HuffmanTree DeleteMin(MinHeap H){int parent, child;int temp;//第一步,先把堆的根部拿走HuffmanTree ans = H->data[H->size--];//将ans的值保存起来temp = H->data[H->size]->Weight;//将下标最大的那个取出来,放在第一个,准备依次向下寻找,小的就上来,大的就下去for (parent = 1; parent * 2 <= H->size; parent = child){//下面寻找最小的儿子child = parent * 2;//找到爸爸节点的儿子if ((child != H->size) && (H->data[child + 1]->Weight < H->data[child]->Weight))child++;//如果说右儿子比左儿子要小,那么左儿子胜出。因为我们这里建立的是最小堆。//下面进行替换if (temp <= H->data[child]->Weight) break;else{H->data[parent]->Weight = H->data[child]->Weight;}}H->data[parent]->Weight = temp;return ans;}//最小堆的插入.插入一定要从下往上插入void Insert(HuffmanTree Item,MinHeap H){int i;H->size++;for (i = H->size; H->data[i/2]->Weight > Item->Weight; i/=2)//当父亲比插入值大的时候,就一直循环{H->data[i]->Weight = H->data[i/2]->Weight;//父亲比插入值要大,那么父亲就要走到下面去//儿子节点   //父亲的值}H->data[i / 2]->Weight = Item->Weight;}HuffmanTree Huffman(MinHeap H){HuffmanTree T;//最后返回的是哈夫曼树int i;BuildMinHeap(H);//先创建一个堆树for (i = 1; i < H->size; i++){T = (HuffmanTree)malloc(sizeof(struct TreeNode));T->left = DeleteMin(H);//从堆树中弹出一个最小的放到T的左边T->right = DeleteMin(H);//从堆树中弹出一个最小的放到T的右边T->Weight = T->left->Weight + T->right->Weight;Insert(T, H);}T = DeleteMin(H); return T;}

阅读全文
0 0
原创粉丝点击