哈夫曼树的创建 实验报告

代码参考严蔚敏《数据结构》

  1 #include<string.h>
  2 #include<stdlib.h>
  3 #include<stdio.h>
  4
  5 int m,s1,s2;
  6
  7 typedef struct
  8 {
  9     unsigned int weight;
 10     unsigned int parent,lchild,rchild;
 11 } HTNode,*HuffmanTree; //动态分配数组存储哈夫曼树
 12 typedef char *HuffmanCode; //动态分配数组存储哈夫曼编码表
 13
 14 void Select(HuffmanTree HT,int n)
 15 {
 16     int i,j;
 17     for(i = 1; i <= n; i++)
 18         if(!HT[i].parent)
 19         {
 20             s1 = i;
 21             break;
 22         }
 23     for(j = i+1; j <= n; j++)
 24         if(!HT[j].parent)
 25         {
 26             s2 = j;
 27             break;
 28         }
 29     for(i = 1; i <= n; i++)
 30         if((HT[s1].weight>HT[i].weight)&&(!HT[i].parent)&&(s2!=i))
 31             s1=i;
 32     for(j = 1; j <= n; j++)
 33         if((HT[s2].weight>HT[j].weight)&&(!HT[j].parent)&&(s1!=j))
 34             s2=j;
 35 }
 36
 37 void HuffmanCoding(HuffmanTree &HT, HuffmanCode HC[], int *w, int n)
 38 {
 39 // 算法6.13
 40 // w存放n个字符的权值(均>0),构造哈夫曼树HT,
 41 // 并求出n个字符的哈夫曼编码HC
 42     int i, j;
 43     char *cd;
 44     int p;
 45     int cdlen;
 46
 47     if (n<=1)
 48         return;
 49     m = 2 * n - 1;
 50     HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode)); // 0号单元未用
 51     for (i=1; i<=n; i++)   //初始化
 52     {
 53         HT[i].weight=w[i-1];
 54         HT[i].parent=0;
 55         HT[i].lchild=0;
 56         HT[i].rchild=0;
 57     }
 58     for (i=n+1; i<=m; i++)   //初始化
 59     {
 60         HT[i].weight=0;
 61         HT[i].parent=0;
 62         HT[i].lchild=0;
 63         HT[i].rchild=0;
 64     }
 65     puts("\n哈夫曼树的构造过程如下所示:");
 66     printf("HT初态:\n 结点 weight parent lchild rchild");
 67     for (i=1; i<=m; i++)
 68         printf("\n%4d%8d%8d%8d%8d",i,HT[i].weight,
 69                HT[i].parent,HT[i].lchild, HT[i].rchild);
 70     for (i=n+1; i<=m; i++)   // 建哈夫曼树
 71     {
 72 // 在HT[1..i-1]中选择parent为0且weight最小的两个结点,
 73 // 其序号分别为s1和s2。
 74         Select(HT, i-1);
 75         HT[s1].parent = i;
 76         HT[s2].parent = i;
 77         HT[i].lchild = s1;
 78         HT[i].rchild = s2;
 79         HT[i].weight = HT[s1].weight + HT[s2].weight;
 80         printf("\nselect: s1=%d s2=%d\n", s1, s2);
 81         printf(" 结点 weight parent lchild rchild");
 82         for (j=1; j<=i; j++)
 83             printf("\n%4d%8d%8d%8d%8d",j,HT[j].weight,
 84                    HT[j].parent,HT[j].lchild, HT[j].rchild);
 85
 86     }
 87
 88 //------无栈非递归遍历哈夫曼树,求哈夫曼编码
 89     cd = (char *)malloc(n*sizeof(char)); // 分配求编码的工作空间
 90     p = m;
 91     cdlen = 0;
 92     for (i=1; i<=m; ++i) // 遍历哈夫曼树时用作结点状态标志
 93         HT[i].weight = 0;
 94     while (p)
 95     {
 96         if (HT[p].weight==0)   // 向左
 97         {
 98             HT[p].weight = 1;
 99             if (HT[p].lchild != 0)
100             {
101                 p = HT[p].lchild;
102                 cd[cdlen++] =‘0‘;
103             }
104             else if (HT[p].rchild == 0)   // 登记叶子结点的字符的编码
105             {
106                 HC[p] = (char *)malloc((cdlen+1) * sizeof(char));
107                 cd[cdlen] =‘\0‘;
108                 strcpy(HC[p], cd); // 复制编码(串)
109             }
110         }
111         else if (HT[p].weight==1)     // 向右
112         {
113             HT[p].weight = 2;
114             if (HT[p].rchild != 0)
115             {
116                 p = HT[p].rchild;
117                 cd[cdlen++] =‘1‘;
118             }
119         }
120         else     // HT[p].weight==2,退回退到父结点,编码长度减1
121         {
122             HT[p].weight = 0;
123             p = HT[p].parent;
124             --cdlen;
125         }
126     }
127 } // HuffmanCoding
128 int main()
129 {
130     HuffmanTree HT;
131     HuffmanCode *HC;
132     int *w,n,i;
133     puts("输入结点数:");
134     scanf("%d",&n);
135     HC = (HuffmanCode *)malloc(n*sizeof(HuffmanCode));
136     w = (int *)malloc(n*sizeof(int));
137     printf("输入%d个结点的权值\n",n);
138     for(i = 0; i < n; i++)
139         scanf("%d",&w[i]);
140     HuffmanCoding(HT,HC,w,n);
141     puts("\n各结点的哈夫曼编码:");
142     for(i = 1; i <= n; i++)
143         printf("%2d(%4d):%s\n",i,w[i-1],HC[i]);
144     getchar();
145 }

运行结果:

原文地址:https://www.cnblogs.com/FengZeng666/p/10043955.html

时间: 2024-10-07 03:00:43

哈夫曼树的创建 实验报告的相关文章

哈夫曼树的编码实验

Java哈夫曼编码实验--哈夫曼树的建立,编码与解码 建树,造树,编码,解码 一.哈夫曼树编码介绍 1.哈夫曼树: (1)定义:假设有n个权值{w1, w2, ..., wn},试构造一棵含有n个叶子结点的二叉树,每个叶子节点带权威wi,则其中带权路径长度WPL最小的二叉树叫做最优二叉树或者哈夫曼树. (2)特点:哈夫曼树中没有度为1的结点,故由n0 = n2+1以及m= n0+n1+n2,n1=0可推出m=2*n0-1,即一棵有n个叶子节点的哈夫曼树共有2n-1个节点. 2.哈夫曼编码步骤:

新学的代码:哈夫曼树的生成实验

// Haffman.cpp : Defines the entry point for the console application.// #include "stdafx.h"#include <stdio.h>#include <string.h>typedef char DataType; struct element  //结点定义{        DataType data;   float weight;//此字符的权值      int par

哈夫曼树(最优二叉树)的创建

哈夫曼树是带权路径最小的一种特殊二叉树,所以也称最优二叉树. 在这里不讨论基本概念如怎样计算路径等,而仅仅着重于树的创建,详细过程让我们举例而言. 其主要的原理为:将全部节点一開始都视为森林.每次从森林中选取两个根节点权值最小的树合并为一棵新树,新树的根节点大小为两个子节点大小的和,并将这棵新树又一次增加到森林中. 如此一来每一轮操作都能够简化为两个基本操作:合并两棵树.插入新树,直到森林中仅仅剩下一棵树,即是哈夫曼树. 以7个节点的权值分别为 1 3 7 9 12 18 25而言 创建的第一步

详细了解哈夫曼树和背包问题

写在前面 最近在疯狂复习数据结构和算法,虽然看完了一部完整的视频.但是转眼看看自己手中的<剑指Offer>里面还是不是很清楚...而且最近也突然觉得自己知识和别人比起来就是一个渣渣.各种被人家吊打... 这两个算法一个(哈夫曼树)是看最近视频动手实践的,一个(背包问题)是前段时间一个面试里面的题目,当时不知道这是一个系类的问题,昨天和大神聊完天之后才明白.所以乘着短暂的热情还在就记录下来先从哈夫曼树开始!! 1.哈夫曼树(实现基本的编码解码) 简单定义: 给定n个权值作为n个叶子结点,构造一棵

一步一步写算法(之哈夫曼树 下)

原文:一步一步写算法(之哈夫曼树 下) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前面说到了哈夫曼树的创建,那下面一个重要的环节就是哈夫曼树的排序问题.但是由于排序的内容是数据结构,因此形式上说,我们需要采用通用数据排序算法,这在我之前的博客里面已经涉及到了(通用算法设计).所以,我们所要做的就是编写compare和swap两个函数.通用冒泡代码如下所示, void bubble_sort(void* array[], int le

一步一步写算法(之哈夫曼树 上)

原文:一步一步写算法(之哈夫曼树 上) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 在数据传输的过程当中,我们总是希望用尽可能少的带宽传输更多的数据,哈夫曼就是其中的一种较少带宽传输的方法.哈夫曼的基本思想不复杂,那就是对于出现频率高的数据用短字节表示,对于频率比较低得数据用长字节表示. 比如说,现在有4个数据需要传输,分别为A.B.C.D,所以一般来说,如果此时没有考虑四个数据出现的概率,那么我们完全可以这么分配,平均长度为2, /

20172301 哈夫曼树实验报告

20172301 哈夫曼树实验报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 郭恺 学号:20172301 实验教师:王志强老师 实验日期:2018年12月9日 必修/选修: 必修 一.实验内容 二.实验过程 哈夫曼树 哈夫曼(Haffman)树,也称最优二叉树,是指对于一组带有确定权值的叶结点.构造的具有最小带权路径长度的二叉树. 二叉树的路径长度是指由根结点到所有的叶结点的路径长度之和. 一棵二叉树要想它的带权路径长度最小,必须使权值越大的叶结点越靠近根结点,而权值越

20172304 蓝墨云实验哈夫曼树

20172304 蓝墨云实验哈夫曼树 实验要求 设有字符集:S={a,b,c,d,e,f,g,h,i,j,k,l,m,n.o.p.q,r,s,t,u,v,w,x,y,z}. 给定一个包含26个英文字母的文件,统计每个字符出现的概率,根据计算的概率构造一颗哈夫曼树. 并完成对英文文件的编码和解码. 要求: (1) 准备一个包含26个英文字母的英文文件(可以不包含标点符号等),统计各个字符的概率 (2) 构造哈夫曼树 (3) 对英文文件进行编码,输出一个编码后的文件 (4) 对编码文件进行解码,输出

数据结构与算法 -- 哈夫曼树思想与创建详解1

PS:什么是哈夫曼树? 给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近. 计算规则: 假设一组权值,一个权值是一个结点,12  34  2  5  7  ,在这其中找出两个最小的权值,然后组成一个新的权值,再次找出最小的权值结点.如图: 问题: 1:如果程序找出两个最小的权值,把两个权值最小的相加结果再次添加到数组中呢. 2:完成第一步后,又