赫夫曼树(最优二叉树)

。在选择最小s1s2的时候少了一个空语句分号。。调试了好久。。坑爹。

这个是最优的编码策略能达到最少的编码

  1 #include<iostream>
  2 #include<stdio.h>
  3 #include<string.h>
  4 #include<math.h>
  5 #include<queue>
  6 #include<algorithm>
  7 using namespace std;
  8 typedef struct
  9 {
 10     unsigned int weight;
 11     unsigned int parent,lchild,rchild;
 12 }htnode,*huffmantree;
 13 typedef char* huffmancode;
 14 void select(huffmantree *ht,int n,int *s1,int *s2)//赫夫曼树指针
 15 {
 16     int i;
 17     for(i=1;i<=n&&(*ht)[i].parent!=0;i++) ;//!!!!!!!!坑爹
 18         *s1=i;
 19     for(i=1;i<=n;i++)
 20         if((*ht)[i].parent==0&&((*ht)[i].weight<(*ht)[*s1].weight))
 21             *s1=i;
 22     for(i=1;i<=n;i++)
 23         if((*ht)[i].parent==0&&i!=*s1)
 24             break;
 25         *s2=i;
 26     for(i=1;i<=n;i++)
 27         if((*ht)[i].parent==0&&i!=*s1&&((*ht)[i].weight<(*ht)[*s2].weight))
 28                 *s2=i;
 29 }
 30 void huffmancoding(huffmantree *ht,huffmancode *hc,int *w,int n)
 31 {
 32     char *cd;
 33     int m,i,start,f,s1,s2;
 34     unsigned int c;
 35     if(n<=1)return;
 36     m=2*n-1;
 37     *ht=(huffmantree)malloc((m+1)*sizeof(htnode));
 38     for(i=1;i<=n;i++)
 39     {
 40         (*ht)[i].weight=w[i];
 41         (*ht)[i].lchild=0;
 42         (*ht)[i].rchild=0;
 43         (*ht)[i].parent=0;
 44     }//赋值
 45     for(i=n+1;i<=m;i++)//后面空间清零
 46     {
 47         (*ht)[i].weight=0;
 48         (*ht)[i].parent=0;
 49         (*ht)[i].lchild=0;
 50         (*ht)[i].rchild=0;
 51     }
 52     for(i=n+1;i<=m;i++)
 53     {
 54         select(ht,i-1,&s1,&s2);//找最小的s1,s2结点
 55         (*ht)[s1].parent=i;(*ht)[s2].parent=i;
 56         (*ht)[i].lchild=s1;(*ht)[i].rchild=s2;
 57         (*ht)[i].weight=(*ht)[s1].weight+(*ht)[s2].weight;
 58     }
 59     hc=(huffmancode*)malloc((n+1)*sizeof(char*));//n个编码的头指针
 60     cd=(char *)malloc(n*sizeof(char));//当前编码空间
 61     cd[n-1]=‘\0‘;//从右向左放编码,首先放末尾的结束标志
 62     for(i=1;i<=n;i++)//求结点的赫夫曼码
 63     {
 64         start=n-1;
 65         for(c=i,f=(*ht)[i].parent;f!=0;c=f,f=(*ht)[f].parent)
 66         {
 67             if((*ht)[f].lchild==c)
 68                 cd[--start]=‘0‘;
 69             else
 70                 cd[--start]=‘1‘;
 71         }
 72         hc[i]=(char*)malloc((n-start)*sizeof(char));
 73         strcpy(hc[i],&cd[start]);
 74     }
 75     free(cd);
 76     for(i=1;i<=26;i++)
 77         printf("%c---%s\n",i+96,hc[i]);
 78 }
 79 char s[1000];
 80 int a[30]={0};
 81 int main()
 82 {
 83     huffmancode hc;
 84     huffmantree ht;
 85     int n,t,i=0,j,l,r,len;
 86     int *b;
 87     float num=0;
 88     gets(s);
 89     t=strlen(s);
 90     b=(int *)malloc(27*sizeof(int));
 91     while(i<t)
 92     {
 93        if(s[i]>=‘A‘&&s[i]<=‘Z‘)
 94             {a[s[i]-64]++;num++;}
 95        if(s[i]>=‘a‘&&s[i]<=‘z‘)
 96             {a[s[i]-96]++;num++;}
 97        i++;
 98     }
 99     for(i=1;i<=26;i++)
100     {
101         b[i]=(a[i]/num)*10000;
102         printf("%c: %d %.3f---%d\n",i+96,a[i],a[i]/num,b[i]);
103     }
104     huffmancoding(&ht,&hc,b,26);
105     return 0;
106 }
时间: 2024-12-21 12:27:29

赫夫曼树(最优二叉树)的相关文章

由二叉树构造赫夫曼树

赫夫曼树: 假设有n个权值{w1,w2,w3....},试构造一棵具有n个叶子节点的二叉树,每个叶子节点带权为wi,则其中带权路径长度最小的二叉树称为最优二叉树或者叫赫夫曼树. 构造赫夫曼树: 假设有n个权值,则构造出的赫夫曼树有n个叶子节点,n个权值分别设置为w1,w2,....wn,则赫夫曼树的构造规则为: 1.将w1,w2...看成是有n棵树的森林: 2.在森林中选择两个根节点的权值最小的树合并,作为一棵新树的左右子树,且新树的根节点权值为其左右子树根节点权值之和: 3.从森林中删除选取的

javascript实现数据结构: 树和二叉树的应用--最优二叉树(赫夫曼树),回溯法与树的遍历--求集合幂集及八皇后问题

赫夫曼树及其应用 赫夫曼(Huffman)树又称最优树,是一类带权路径长度最短的树,有着广泛的应用. 最优二叉树(Huffman树) 1 基本概念 ① 结点路径:从树中一个结点到另一个结点的之间的分支构成这两个结点之间的路径. ② 路径长度:结点路径上的分支数目称为路径长度. ③ 树的路径长度:从树根到每一个结点的路径长度之和. 以下图为例: A到F :结点路径 AEF : 路径长度(即边的数目) 2 : 树的路径长度:3*1+5*2+2*3=19: ④ 结点的带权路径长度:从该结点的到树的根结

Huffman tree(赫夫曼树、霍夫曼树、哈夫曼树、最优二叉树)

flyfish 2015-8-1 Huffman tree因为翻译不同所以有其他的名字 赫夫曼树.霍夫曼树.哈夫曼树 定义引用自严蔚敏<数据结构> 路径 从树中一个结点到另一个结点之间的分支构成两个结点之间的路径. 路径长度 路径上的分支数目称作路径长度. 树的路径长度 树的路径长度就是从根节点到每一结点的路径长度之和. 结点的带权路径长度 结点的带权路径长度就是从该结点到根节点之间的路径长度与结点上权的乘积. 树的带权路径长度 树的带权路径长度就是树中所有叶子结点的带权路径长度之和,通常记做

php 二叉树 与赫夫曼树

在学习图之前,中间休息了两天,感觉二叉树需要消化一下.所以中间去温习了下sql,推荐一本工具书<程序员的SQL金典>看名字不像一本好书,但是作为一个不错的SQL工具书还是可以小小备忘一下.涵盖内容不详细但是挺广,覆盖多种主流数据库 言归正传,以前知道折半查找,二叉树的概念也是感觉挺有意思,二叉树的实现有一个案例很不错,代码如下 class BiNode{ public $data; public $lchild; public $rchild; public function __constr

数据结构之二叉树,赫夫曼树(C++版)

#include <iostream>#include <windows.h>#include <stdlib.h>#include <string.h>#define MAXLISTSIZE 100 //预设的存储空间最大容量#define FALSE 0#define TRUE 1using namespace std;typedef char ElemType; typedef struct BiTNode{ ElemType data; struct

基础数据结构-二叉树-赫夫曼树的解码(详解)

本篇是上一篇赫夫曼树构建与编码的后续,稍微详细讲一下解码的算法. Huffman解码算法流程: 1.定义指针p指向赫夫曼树结点,实际是记录结点数组的下标: 2.定义指针i指向编码串,定义ch逐个取编码串的字符: 3.初始化:读入编码串,设置p指向根结点,i为0: 4.执行以下循环: a)取编码串的第i个字符放入ch: b)如果ch是字符0,表示往左孩子移动,则p跳转到右孩子: c)如果ch是字符1,表示往右孩子移动,则p跳转到右孩子: d)如果ch非0非1,表示编码串有错误,输出error表示解

赫夫曼树JAVA实现及分析

一,介绍 1)构造赫夫曼树的算法是一个贪心算法,贪心的地方在于:总是选取当前频率(权值)最低的两个结点来进行合并,构造新结点. 2)使用最小堆来选取频率最小的节点,有助于提高算法效率,因为要选频率最低的,要么用排序,要么用堆.用堆的话,出堆的复杂度为O(logN),而向堆中插入一个元素的平均时间复杂度为O(1),在构建赫夫曼树的过程中,新生成的结点需要插入到原来的队列中,故用堆来维持这种顺序比排序算法要高效地多. 二,赫夫曼算法分析 ①用到的数据结构分析 首先需要构造一棵赫夫曼树,因此需要二叉链

13.赫夫曼树及其应用

一.赫夫曼树定义与原理 1.路径长度:从树中一个结点到另一个结点之间的分支构成两个结点之间的路径,路径上的分支数目称作路径的长度; 2.树的路径长度:即从树根到每一结点的路径长度之和; 3.结点的带权的路径长度:即从该结点从到树根之间的路径长度与结点上权的乘积; 4.树的带权路径长度:为树中所有叶子结点的带权路径长度之和; 5.赫夫曼树定义:假设有n个权值{w1,w2,....,wn},构造一颗有n个叶子结点的二叉树,每个叶子结点带权wk,每个叶子的路径长度为lk,则其中带权路径长度WPL最小的

赫夫曼树

一.前言 赫夫曼树,又称最优树,是一类带权路径长度最短的树. 二.基础知识 1.路径长度:从树中一个结点到另一个结点之间的分支构成这两个结点之间的路径,路径上分支数目称为路径长度. 2.树的路径长度:是从树根到每一个结点的路径长度之和.完全二叉树就是路径长度最短的二叉树. 3.树带权路径长度:为树中所有叶子结点的带权路径长度之和(记做WPL). 4.最优二叉树或者赫夫曼树:假设有n个权值(w1,w2,w3,w4,,,,,,wn).试构造一棵有n个叶子结点的二叉树,每个叶子结点带权为wi,其中称带