精华内容
下载资源
问答
  • 刚刚学习了哈夫曼树算法而且画了一张方便理解。。迫不及待的贴出来嘚瑟 hh~ 哈夫曼算法基本思想: (1) 以权值分别为W1,W2...Wn的n各结点,构成n棵二叉树T1,T2,...Tn并组成森林F={T1,T2,...Tn},其中每...

    我胡汉三又肥来了。。
    刚刚学习了哈夫曼树算法而且画了一张图方便理解。。迫不及待的贴出来嘚瑟 hh~
    哈夫曼算法基本思想:

    (1) 以权值分别为W1,W2...Wn的n各结点,构成n棵二叉树T1,T2,...Tn并组成森林F={T1,T2,...Tn},其中每棵二叉树 Ti仅有一个权值为 Wi的根结点;

    (2) 在F中选取两棵根结点权值最小的树作为左右子树构造一棵新二叉树,并且置新二叉树根结点权值为左右子树上根结点的权值之和(根结点的权值=左右孩子权值之和,叶结点的权值= Wi);

    (3) 从F中删除这两棵二叉树,同时将新二叉树加入到F中;

    (4) 重复(2)、(3)直到F中只含一棵二叉树为止,这棵二叉树就是Huffman树。
      在这里插入图片描述
     哈夫曼算法的存储结构

    考虑到对于有n个叶子结点的哈夫曼树有2n-1个结点,并且进行n-1次合并操作,为了便于选取根节点权值最小的二叉树以及合并操作,设置一个数组haftree[2n-1],保存哈夫曼树中的各个结点的信息,数组元素的结点结构如下图所示:
    在这里插入图片描述
    weight保存结点权值;

    lchild保存该节点的左孩子在数组中的下标;

    rchild保存该节点的右孩子在数组中的下标;

    parent保存该节点的双亲孩子在数组中的下标。

    struct element
    {
    int weight; // 权值域
    int lchild, rchild, parent; // 该结点的左、右、双亲结点在数组中的下标
    };
    哈夫曼算法C++实现
    https://www.cnblogs.com/smile233/p/8184492.html

    展开全文
  • 哈夫曼树 两份报告 c语言代码 流程图哈夫曼树 两份报告 c语言代码 流程图哈夫曼树 两份报告 c语言代码 流程图哈夫曼树 两份报告 c语言代码 流程图
  • 哈夫曼树哈夫曼树编码

    千次阅读 2015-09-09 15:50:57
    本文转自哈夫曼树哈夫曼树编码 在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(HUFFMAN) 树和哈夫曼编码。哈夫曼编码是哈夫曼树的一个应用。哈夫曼编码应用广泛,如 JPEG中就应用...

    本文转自哈夫曼树及哈夫曼树编码

    在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(HUFFMAN)

    树和哈夫曼编码。哈夫曼编码是哈夫曼树的一个应用。哈夫曼编码应用广泛,如

    JPEG中就应用了哈夫曼编码。 首先介绍什么是哈夫曼树。哈夫曼树又称最优二叉树,

    是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点

    的权值乘上其到根结点的 路径长度(若根结点为0层,叶结点到根结点的路径长度

    为叶结点的层数)。树的带权路径长度记为WPL= (W1*L1+W2*L2+W3*L3+...+Wn*Ln)

    ,N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径

    长度为Li(i=1,2,...n)。可以证明哈夫曼树的WPL是最小的。

    哈夫曼编码步骤:

    一、对给定的n个权值{W1,W2,W3,...,Wi,...,Wn}构成n棵二叉树的初始集合F= {T1,T2,T3,...,Ti,...,Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。(为方便在计算机上实现算 法,一般还要求以Ti的权值Wi的升序排列。)
    二、在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。
    三、从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F中。
    四、重复二和三两步,直到集合F中只有一棵二叉树为止。

    简易的理解就是,假如我有A,B,C,D,E五个字符,出现的频率(即权值)分别为5,4,3,2,1,那么我们第一步先取两个最小权值作为左右子树构造一个新树,即取1,2构成新树,其结点为1+2=3,如图:

    12

    虚线为新生成的结点,第二步再把新生成的权值为3的结点放到剩下的集合中,所以集合变成{5,4,3,3},再根据第二步,取最小的两个权值构成新树,如图:

    13

    再依次建立哈夫曼树,如下图:

    14

    其中各个权值替换对应的字符即为下图:

    15

    所以各字符对应的编码为:A->11,B->10,C->00,D->011,E->010

    霍夫曼编码是一种无前缀编码。解码时不会混淆。其主要应用在数据压缩,加密解密等场合。

     

    C语言代码实现:

    /*-------------------------------------------------------------------------
     * Name:   哈夫曼编码源代码。
     * Date:   2011.04.16
     * Author: Jeffrey Hill+Jezze(解码部分)
     * 在 Win-TC 下测试通过
     * 实现过程:着先通过 HuffmanTree() 函数构造哈夫曼树,然后在主函数 main()中
     *           自底向上开始(也就是从数组序号为零的结点开始)向上层层判断,若在
     *           父结点左侧,则置码为 0,若在右侧,则置码为 1。最后输出生成的编码。
     *------------------------------------------------------------------------*/
    #include <stdio.h>
    #include<stdlib.h>
     
    #define MAXBIT      100
    #define MAXVALUE  10000
    #define MAXLEAF     30
    #define MAXNODE    MAXLEAF*2 -1
     
    typedef struct 
    {
        int bit[MAXBIT];
        int start;
    } HCodeType;        /* 编码结构体 */
    typedef struct
    {
        int weight;
        int parent;
        int lchild;
        int rchild;
        int value;
    } HNodeType;        /* 结点结构体 */
     
    /* 构造一颗哈夫曼树 */
    void HuffmanTree (HNodeType HuffNode[MAXNODE],  int n)
    { 
        /* i、j: 循环变量,m1、m2:构造哈夫曼树不同过程中两个最小权值结点的权值,
            x1、x2:构造哈夫曼树不同过程中两个最小权值结点在数组中的序号。*/
        int i, j, m1, m2, x1, x2;
        /* 初始化存放哈夫曼树数组 HuffNode[] 中的结点 */
        for (i=0; i<2*n-1; i++)
        {
            HuffNode[i].weight = 0;//权值 
            HuffNode[i].parent =-1;
            HuffNode[i].lchild =-1;
            HuffNode[i].rchild =-1;
            HuffNode[i].value=i; //实际值,可根据情况替换为字母  
        } /* end for */
     
        /* 输入 n 个叶子结点的权值 */
        for (i=0; i<n; i++)
        {
            printf ("Please input weight of leaf node %d: \n", i);
            scanf ("%d", &HuffNode[i].weight);
        } /* end for */
     
        /* 循环构造 Huffman 树 */
        for (i=0; i<n-1; i++)
        {
            m1=m2=MAXVALUE;     /* m1、m2中存放两个无父结点且结点权值最小的两个结点 */
            x1=x2=0;
            /* 找出所有结点中权值最小、无父结点的两个结点,并合并之为一颗二叉树 */
            for (j=0; j<n+i; j++)
            {
                if (HuffNode[j].weight < m1 && HuffNode[j].parent==-1)
                {
                    m2=m1; 
                    x2=x1; 
                    m1=HuffNode[j].weight;
                    x1=j;
                }
                else if (HuffNode[j].weight < m2 && HuffNode[j].parent==-1)
                {
                    m2=HuffNode[j].weight;
                    x2=j;
                }
            } /* end for */
                /* 设置找到的两个子结点 x1、x2 的父结点信息 */
            HuffNode[x1].parent  = n+i;
            HuffNode[x2].parent  = n+i;
            HuffNode[n+i].weight = HuffNode[x1].weight + HuffNode[x2].weight;
            HuffNode[n+i].lchild = x1;
            HuffNode[n+i].rchild = x2;
     
            printf ("x1.weight and x2.weight in round %d: %d, %d\n", i+1, HuffNode[x1].weight, HuffNode[x2].weight);  /* 用于测试 */
            printf ("\n");
        } /* end for */
      /*  for(i=0;i<n+2;i++)
        {
            printf(" Parents:%d,lchild:%d,rchild:%d,value:%d,weight:%d\n",HuffNode[i].parent,HuffNode[i].lchild,HuffNode[i].rchild,HuffNode[i].value,HuffNode[i].weight);
                      }*///测试 
    } /* end HuffmanTree */
     
    //解码 
    void decodeing(char string[],HNodeType Buf[],int Num)
    {
      int i,tmp=0,code[1024];
      int m=2*Num-1;
      char *nump;
      char num[1024];
      for(i=0;i<strlen(string);i++)
      {
       if(string[i]=='0')
      num[i]=0;        
      else
      num[i]=1;                    
      } 
      i=0;
      nump=&num[0];
      
     while(nump<(&num[strlen(string)]))
     {tmp=m-1;
      while((Buf[tmp].lchild!=-1)&&(Buf[tmp].rchild!=-1))
      {
      
       if(*nump==0)
       {
         tmp=Buf[tmp].lchild ;          
       } 
       else tmp=Buf[tmp].rchild;
       nump++;
            
      } 
      
      printf("%d",Buf[tmp].value);                                  
     }
     
      
    }
     
     
    int main(void)
    {
        
        HNodeType HuffNode[MAXNODE];            /* 定义一个结点结构体数组 */
        HCodeType HuffCode[MAXLEAF],  cd;       /* 定义一个编码结构体数组, 同时定义一个临时变量来存放求解编码时的信息 */
        int i, j, c, p, n;
        char pp[100];
        printf ("Please input n:\n");
        scanf ("%d", &n);
        HuffmanTree (HuffNode, n);
       
        
        for (i=0; i < n; i++)
        {
            cd.start = n-1;
            c = i;
            p = HuffNode[c].parent;
            while (p != -1)   /* 父结点存在 */
            {
                if (HuffNode[p].lchild == c)
                    cd.bit[cd.start] = 0;
                else
                    cd.bit[cd.start] = 1;
                cd.start--;        /* 求编码的低一位 */
                c=p;                    
                p=HuffNode[c].parent;    /* 设置下一循环条件 */
            } /* end while */
            
            /* 保存求出的每个叶结点的哈夫曼编码和编码的起始位 */
            for (j=cd.start+1; j<n; j++)
            { HuffCode[i].bit[j] = cd.bit[j];}
            HuffCode[i].start = cd.start;
        } /* end for */
        
        /* 输出已保存好的所有存在编码的哈夫曼编码 */
        for (i=0; i<n; i++)
        {
            printf ("%d 's Huffman code is: ", i);
            for (j=HuffCode[i].start+1; j < n; j++)
            {
                printf ("%d", HuffCode[i].bit[j]);
            }
            printf(" start:%d",HuffCode[i].start);
           
            printf ("\n");
            
        }
    /*    for(i=0;i<n;i++){
        for(j=0;j<n;j++)
            {
                 printf ("%d", HuffCode[i].bit[j]);           
            }
            printf("\n");
            }*/
        printf("Decoding?Please Enter code:\n");
        scanf("%s",&pp);
    decodeing(pp,HuffNode,n);
        getch();
        return 0;
    }

    展开全文
  • 哈夫曼树

    2018-11-24 18:58:00
    数据结构——哈夫曼树 哈夫曼树又被称为最优二叉树,是指一类带权路径长度最小的二叉树, 哈夫曼树的遍历不是唯一的,因为在构造树的时候左右子树的位置是不同的。 哈夫曼树的构造思想如下 1:在给定权值的结点集合中...

    数据结构——哈夫曼树

    哈夫曼树又被称为最优二叉树,是指一类带权路径长度最小的二叉树,
    哈夫曼树的遍历不是唯一的,因为在构造树的时候左右子树的位置是不同的。
    哈夫曼树的构造思想如下
    1:在给定权值的结点集合中,每个结点都是一颗独立的二叉树,并且左右子树为空,且只有一个根结点。
    2:在集合中找到俩个最小的结点,并且组成一个新的结点,这俩个最小的分别为这个新结点的左右子树。新的结点为这两个结点的根结点。并且删除这俩个最小的结点,将新组成的结点添加集合中。
    3:直到集合中元素长度不为1的时候 重复2

    例如:
    {1,2,3,4}构成的哈夫曼树是什么?
    [图片上传失败...(image-588d50-1543055316769)]

    在这里用链表实现,因为经常要删除和添加,链表比较好。
    流程图如下
    [图片上传失败...(image-f1b818-1543055316770)]


    代码如下:

    //  main.cpp
    //  hafuman
    //
    //  Created by 橘子和香蕉 on 2018/11/22.
    //  Copyright © 2018 橘子和香蕉. All rights reserved.
    //
    
    #include <iostream>
    using namespace std;
    typedef struct node{
        int data;
        node * parent;
        node *lchild;
        node *rchild;
        node *next;
    }node;
    
    class Tree{
    private:
        node* head;
        node *hufmTreeHead;
        int length;
    #pragma 私有函数声明
        void inorderNode(node *p);//中序遍历
        void findMinNodeandDelete(node *&p);//找最小的结点并且删除掉
        void addNode(node *p1);//两个参数组成一个新的结点然后添加这个新的结点
    public:
        Tree(){head = new node; head->lchild = head->rchild=head->parent=head->next =  NULL;hufmTreeHead = NULL; }
        void initTreeList();//创建一条链表
        void createHufmTree();//创建一个二叉树
        void inorderTree();//中序遍历
        void printNode();//输出所有链表中的结点
    };
    #pragma 私有函数的实现开始
    void Tree::inorderNode(node *p){
        if(p ==  NULL) return;
        else{
            inorderNode(p->lchild);
            cout<<"data: "<<p->data<<"\n";
            inorderNode(p->rchild);
        }
    }
    void Tree::findMinNodeandDelete(node *&p){
        /*查找分为两步;
         1:遍历链表,找到最小值所在的结点的位置,记下这个位置
         2:遍历链表,找个这个结点。
         
         因为不能在第一遍遍历链表的时候同时删除这个最小值所在的单向链表。同时也不能删除这个结点,因为这个结点还是留下来联接。
         */
        node *h1 = head;
        node *h = h1->next;
        int min = INT_MAX;
        while ( h != NULL) {
            if(h->data < min){
                min = h->data;
                p = h;
            }
            h = h->next;
        }
        h = h1->next;
        while (h != NULL) {
            if(h == p){
                h1->next = h->next;
                break;
            }
            h1 = h;
            h = h->next;
        }
        length--;//删除一个结点length-1;
    }
    void Tree::addNode(node *p){
        
        //头插法添加结点每次添加的都是在结点的头部
        p->next = head->next;
        head->next = p;
        length++;//添加一个新的结点length++;
    }
    
    #pragma 私有函数实现结束
    
    
    #pragma 公有函数实现开始
    void Tree::initTreeList(){
        cout<<"input data length:\n";
        int length;
        cin>>length;
        this->length = length;//数据长度
        cout<<"begin  input node data:\n";
        int data = 0;
        node *h = head;
        node* p;
        for (int i = 0; i<length; i++) {
            cout<<"input data: \t";
            cin>>data;
            p = new node;
            p->data= data;
            p->lchild = p->rchild=p->parent=p->next =  NULL;
            h->next = p;
            h = p;
            
        }
        
    }
    void Tree::createHufmTree(){
        node *p1,*p2;//找到的新结点
        while (length > 1) {
            findMinNodeandDelete(p1);
            findMinNodeandDelete(p2);
            node *n  = new node;//通过p1和p2组成一个新的结点;
            n->data = p1->data+p2->data;
            n->lchild = p1;
            n->rchild = p2;
            n->next = NULL;
            p1->parent = p2->parent = n;
            addNode(n);
        }
        hufmTreeHead = head->next;
        cout<<"hufmanHead:"<<hufmTreeHead->data<<endl;
    }
    
    void Tree::inorderTree(){
        cout<<"inorderTree-------------------------------------------\n";
        node *p = hufmTreeHead;
        inorderNode(p);
        cout<<endl;
        cout<<"inorderTree___________________________________________\n";
    }
    
    void Tree::printNode(){
        cout<<endl;
        cout<<"printNode begin---------------------------\n";
        node *h = head->next;
        cout<<"length"<<length<<";";
        while (h !=  NULL) {
            cout<<"h->data:"<<h->data<<endl;
            h = h->next;
        }
        cout<<"printNode finish_____________________\n";
    }
    
    #pragma 公有函数的实现的结束
    int main(){
        Tree t;
        t.initTreeList();
        t.printNode();
        t.createHufmTree();
        t.inorderTree();
        return 1;
    }
    
    
    
    展开全文
  • 哈夫曼树、哈夫曼编码详解

    千次阅读 多人点赞 2021-06-17 09:33:06
    哈夫曼树、哈夫曼编码,也就这么一回事,一文搞懂!

    哈夫曼树介绍

    hello,大家好,我是bigsai。本以为哈夫曼树、哈夫曼编码很难,结果很容易嘛!

    哈夫曼树、哈夫曼编码很多人可能听过,但是可能并没有认真学习了解,今天这篇就比较详细的讲一下哈夫曼树。

    首先哈夫曼树是什么?

    哈夫曼树的定义:给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree),哈夫曼树是带权路径长度最短的树。权值较大的结点离根较近。

    那这个树长啥样子呢?例如开始2,3,6,8,9权值节点构成的哈夫曼树是这样的:

    image-20210616113835069

    从定义和图上你也可以发现下面的规律:

    • 初始节点都在树的叶子节点上
    • 权值大的节点离根更近
    • 每个非叶子节点都有两个孩子(因为我们自下向上构造,两个孩子构成一个新树的根节点)

    你可能会好奇这么一个哈夫曼树是怎么构造的,其实它是按照一个贪心思想和规则构造,而构造出来的这个树的权值最小。这个规则下面会具体讲解。

    哈夫曼树非常重要的一点:WPL(树的所有叶结点的带权路径长度之和)。至于为什么按照哈夫曼树方法构造得到的权重最小,这里不进行证明,但是你从局部来看(三个节点)也要权值大的在上一层WPL才更低。

    WPL计算方法: WPL=求和(Wi * Li)其中Wi是第i个节点的权值(value)。Li是第i个节点的长(深)度.

    例如上面 2,3,6,8,9权值节点构成的哈夫曼树的WPL计算为(设根为第0层):

    比如上述哈夫曼树的WPL为:2*3+3*3+6*2+8*2+9*2=(2+3)*3+(6+8+9)*2=61.

    既然了解了哈夫曼树的一些概念和WPL的计算方式,下面看看哈夫曼树的具体构造方式吧!

    哈夫曼树构造

    初始给一个森林有n个节点。我们主要使用贪心的思想来完成哈夫曼树的构造:

    1. 在n个节点找到两个最小权值节点(根),两个为叶子结构构建一棵新树(根节点权值为左右孩子权值和)
    2. 先删掉两个最小节点(n-2)个,然后加入构建的新节点(n-1)个
    3. 重复上面操作,一直到所有节点都被处理

    在具体实现上,找到最小两个节点需要排序操作,我们来看看2,6,8,9,3权值节点构成哈夫曼树的过程。

    初始时候各个节点独立,先将其排序(这里使用优先队列),然后选两个最小节点(抛出)生成一个新的节点,再将其加入优先队列中,此次操作完成后优先队列中有5,6,8,9节点

    image-20210616002804144

    重复上面操作,这次结束 队列中有11,8,9节点(排序后8,9,11)

    image-20210616003017369

    如果队列为空,那么返回节点,并且这个节点为整个哈夫曼树根节点root。

    否则继续加入队列进行排序。重复上述操作,直到队列为空

    image-20210616004133250

    image-20210616004627977

    在计算带权路径长度WPL的时候,需要重新计算高度(从下往上),因为哈夫曼树是从下往上构造的,并没有以常量维护高度,可以构造好然后计算高度。

    具体代码实现

    import java.util.ArrayDeque;
    import java.util.ArrayList;
    import java.util.Comparator;
    import java.util.List;
    import java.util.PriorityQueue;
    import java.util.Queue;
    
    public class HuffmanTree {	
    	public static class node
    	{
    		int value;
    		node left;
    		node right;
    		int deep;//记录深度
    		public node(int value) {
    			this.value=value;
    			this.deep=0;
    		}
    		public node(node n1, node n2, int value) {
    			this.left=n1;
    			this.right=n2;
    			this.value=value;
    		}
    	}
    	private node root;//最后生成的根节点
    	List<node>nodes;
    	public HuffmanTree() {
    		this.nodes=null;
    	}
    	public HuffmanTree(List<node>nodes)
    	{
    		this.nodes=nodes;
    	}
    	public void createTree() {
    	   Queue<node>q1=new PriorityQueue<node>(new Comparator<node>() {
          public int compare(node o1, node o2) {
            return o1.value-o2.value;
          }});
    	   q1.addAll(nodes);
    	   while(!q1.isEmpty()){
    		   node n1=q1.poll();
    		   node n2=q1.poll();
    		  node parent=new node(n1,n2,n1.value+n2.value);
    		  if(q1.isEmpty()){
    			  root=parent;return;
    		  }
    		  q1.add(parent);
    	   }
    	}
    	public int getweight() {
    		Queue<node>q1=new ArrayDeque<node>();
    		q1.add(root);
    		int weight=0;
    		while (!q1.isEmpty()) {
    			node va=q1.poll();
    			if(va.left!=null){
    				va.left.deep=va.deep+1;va.right.deep=va.deep+1;
    				q1.add(va.left);q1.add(va.right);
    			}
    			else {
    				weight+=va.deep*va.value;
    			}
    		}
    		return weight;
    	}
    	public static void main(String[] args) {
    		List<node>list=new ArrayList<node>();
    		list.add(new node(2));
    		list.add(new node(3));
    		list.add(new node(6));
    		list.add(new node(8));list.add(new node(9));
    		HuffmanTree tree=new HuffmanTree();
    		tree.nodes=list;
    		tree.createTree();
    		System.out.println(tree.getweight());
    	}
    }
    
    

    输出结果:

    61

    哈夫曼编码

    除了哈夫曼树你听过,哈夫曼编码你可能也听过,但是不一定了解它是个什么玩意儿,哈夫曼编码其实就是哈夫曼树的一个非常重要的应用,在这里就简单介绍原理并不详细实现了。

    哈夫曼编码定义:哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码(有时也称为霍夫曼编码)。

    哈夫曼编码的目的是为了减少存储体积,以一个连续的字符串为例,抛开编程语言中实际存储,就拿

    aaaaaaaaaabbbbbcccdde

    这个字符串来说,在计算机中如果每个字符都是定长存储(假设长为4的二进制存储),计算机只知道0和1的二进制,假设

    a:0001

    b:0010

    c:0011

    d:0100

    e:0101

    那么上面字符串可以用二进制存储是这样的

    000100010001000100010001……0101

    如果每个字符编码等长,那么就没有空间优化可言,都是单个字符长度 * 字符个数。但是如果每个字符编码不等长,那么设计的开放性就很强了。

    比如一个字符串aaaaabb

    如果设计a为01,b设计为1。那么二进制就为:010101010111

    如果设计a为1,b设计为01。那么二进制就为:111110101

    如果设计a为1,b设计为0。那么二进制就为:1111100

    你看,在计算机的01二进制世界中,明显第二种比第一种优先,第三种又比第二种优先。所以,设计编码要考虑让出现多的尽量更短,出现少的稍微长点没关系

    但是,你需要考虑的一个问题是,二进制开始0,1,01,10,11这个顺序 ,如果来了001它到底是0,0,1还是0,01呢?所以编码不等长的时候你要考虑到这个编码要有唯一性不能出现歧义。这个怎么搞呢?

    简单啊,计算机只知道01二进制,而二叉树刚好有左右两个节点,至于一个字符它如果是对应叶子节点,那么就可以直接确定,也就是这个数值如果映射成一个二叉树字符不能存在非叶子节点上。

    image-20210616134909721

    所以,哈夫曼编码具体流程就很清晰了,先统计字符出现的次数,然后将这个次数当成权值按照上面介绍的方法构造一棵哈夫曼树,然后树的根不存,往左为0往右为1每个叶子节点得到的二进制数字就是它的编码,这样频率高的字符在上面更短在整个二进制存储中也更节省空间。

    结语

    哈夫曼树还是比较容易理解,主要构造利用贪心算法的思想去从下往上构建,哈夫曼编码相信看了你也有所收获,有兴趣可以自己实现一下哈夫曼编码的代码(编码、解码)。本人水平有限,如果有错误还希望大佬指正!

    推荐阅读:
    排个课表学会了拓扑排序!有点意思
    师兄刷题笔记、算法小抄、面试突击版必备资源,帮你走上人生巅峰
    考研学弟问的n个问题,梳理一下分享给大家

    文章结束,如果大家感觉不错,欢迎关注、点赞、收藏一键三连支持一下!同时我也有个同名公众号:bigsai 欢迎交流,一起进步!

    展开全文
  • 哈夫曼树以及哈夫曼编码的构造步骤

    万次阅读 多人点赞 2018-06-11 20:49:05
    注意:哈夫曼树并不唯一,但带权路径长度一定是相同的。(1)8个结点的权值大小如下:(2)从19,21,2,3,6,7,10,32中选择两个权小结点。选中2,3。同时算出这两个结点的和5。(3)从19,21,6,7,10,32,5中...
  • 哈夫曼树和哈夫曼编码的Java实现,供新手学习使用。希望能给需要的人以帮助。
  • 哈夫曼树中的查找算法(Select) 哈夫曼树的构建(HuffmanTree) 哈夫曼编码的构建(HuffmanCoding) 打印哈夫曼树表(Print) 打印权值及其编码(Inputcode) 完整代码: #include <stdio.h> #include <stdlib....
  • 哈夫曼树及其编码

    2013-11-26 19:06:43
    哈夫曼树及其编码,在学习数据结构及C++的时候是有很好的帮助
  • 构造二叉搜索代码实现:平衡二叉搜索(AVL)什么是平衡二叉搜索?AVL的节点数据结构AVL构造左旋右旋双旋转新增节点(背多分)LL(右旋)RR(左旋)LRRL插入节点 ,什么是是我们计算机中非常重要的...
  • 定义哈夫曼树的存储结构;输入要编码的字符权重,根据权重建立哈夫曼树,并进行编码,最后输出哈夫曼编码。
  • 哈夫曼树的构造过程

    万次阅读 多人点赞 2017-07-25 23:42:57
    今天做题的时候,遇到了一个关于哈夫曼树的题,由于一直不是很明白哈夫曼树的构造过程,所以找了很多资料都不是特别清楚的,直到我遇到了这篇文章,哈哈,在此分享给大家哦! 注意:哈夫曼树并不唯一,但...
  • 一、课程设计题目:哈夫曼树应用 二、课程设计要求: 1) 从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树并将它存于文件hfmTree中.将已在内存中的哈夫曼树以直观的方式(比如树)显示在终端上; 2) 利用...
  • 哈夫曼树,也叫最优二叉树。在含有给定的n个带权叶子结点的二叉树中,WPL最小的树。其中,结点的权指的是某种特定含义的数值;带权路径长度值根到结点的路径长度乘以结点权值;树的带权路径长度(WPL)是指树中所有...
  • 哈夫曼树又称 “最优树” , 是一类带权路径最短的树,这种树有着广泛的应用 哈夫曼树作用于内存压缩,使得空间更加节省。 路径:在一棵树中,一个结点到另一个结点之间的通路,称为路径。 1 中,从根结点...
  • 建立哈夫曼树 编码 译码 详细的步骤 程序和流程图 心得体会等
  • 哈夫曼树和哈夫曼编码 文章目录哈夫曼树和哈夫曼编码哈夫曼树引子定义与原理 哈夫曼(Huffman)编码是个实用的压缩编码方案。 哈夫曼树 引子 我们观察以下代码: if( a < 60) { printf("不及格\n"); }else if( a...
  • . 教育资料 软件学院设计性实验报告 专业...理解哈夫曼树的特征及其应用在对哈夫曼树进行理解的基础上构造哈夫曼树并用构造的哈夫曼树进行编码和译码通过该实验使学生对数据结构的应用有更深层次的理解 实验仪器或设备
  • 数据结构课设-哈夫曼树

    千次阅读 2018-12-29 00:22:58
    1、建立哈夫曼树:读入文件(*.souce),统计文件中字符出现的频度,并以这些字符的频度作为权值,建立哈夫曼树。 2、编码:利用已建立好的哈夫曼树,获得各个字符的哈夫曼编码,并对正文进行编码,然后输出编码结果...
  • 数据结构——哈夫曼树 哈夫曼树又被称为最优二叉树,是指一类带权路径长度最小的二叉树,哈夫曼树的遍历不是唯一的,因为在构造树的时候左右子树的位置是不同的。哈夫曼树的构造思想如下 1:在给定权值的结点集合中,...
  • 基于哈夫曼树的文本数据压缩 课题内容: 1、学习哈夫曼编码原理和哈夫曼树的构造方法; 2、针对序列(whatever is worth doing is worth doing well,包含空格),利用matlab绘制对应的哈夫曼树以及计算编码后的序列...
  • 数据结构课程设计报告设计题目:哈夫曼树应用专 业 : 软件工程班 级 : 软件学 生 :学 号 :指导教师 : 罗作民 / 张翔起止时间 :2011-07-04—2011-07-082011 年 春季 学期目 录一.具体任务…..21功能…………...
  • 哈夫曼树建立.cpp

    2020-01-04 17:30:41
    自己码的C语言哈弗曼的建立,代码格式整齐,清晰易懂,能正确运行,包含文件的编码解码和压缩功能,很不错的代码,很容易用其他语言复现
  • 老师看过的,得分很高!有详细的代码和流程图!果断下载呀,亲!
  • 哈夫曼树及其应用

    千次阅读 2016-05-17 07:06:31
    哈夫曼树树,也称最优二叉树,是指对于一组带有确定权值的叶结点,构造的具有最小带权路径长度的二叉树。 二叉树的路径长度是指由根结点到所有叶结点的路径之和。设二叉树具有n个带权值的叶结点,那么从根结点到各个...
  • C++实现哈夫曼树的编码和译码

    千次阅读 2020-05-22 16:30:08
    C++实现哈夫曼树的编码和译码 #include <iostream> #include <map> #include <string> #include <vector> using namespace std; const int INF = 65535; //哈夫曼树 typedef struct Node {...
  • 一、哈夫曼树 1. 哈夫曼树也称最优二叉树。  叶子节点的权值是对叶子节点赋予的一个有意义的数值量。  设二叉树具有 n 个带权值的叶子结点,从根节点到各个叶子结点的路径长度与相应叶子结点权值的乘积之和叫做...
  • 这里写自定义目录标题JavaFX实现哈夫曼树和哈夫曼编码的GUI界面的显示原理及作用GUI界面功能如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右...
  • 一、哈夫曼树 具有n个权值的n个叶子结点,构造出一个二叉树,使得该树的带权路径长度(WPL)最小,则称此二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。 注意:哈夫曼树是带权路径长度最短的树,且权值越...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,522
精华内容 608
关键字:

哈夫曼树流程图