精华内容
下载资源
问答
  • 哈夫曼算法

    2018-03-09 12:41:06
    使用哈夫曼算法对字符进行排序,通过字符出现的权值求出哈夫曼树,并给出哈夫曼编码
  • a.b.c.d.e 对应出现频率为4,6,11,13,15 用Python实现哈夫曼代码可参考:哈夫曼树的 Python 实现 或者:https://blog.csdn.net/qq_42098718/article/details/102809485

    a.b.c.d.e 对应出现频率为4,6,11,13,15

    用Python实现哈夫曼代码可参考:哈夫曼树的 Python 实现   或者:https://blog.csdn.net/qq_42098718/article/details/102809485

    .选择排序:不稳定,时间复杂度 O(n^2)

    插入排序:稳定,时间复杂度 O(n^2)

    冒泡排序:稳定,时间复杂度 O(n^2)

    堆排序:不稳定,时间复杂度 O(nlog n)

    归并排序:稳定,时间复杂度 O(nlog n)

    快速排序:不稳定,时间复杂度 最理想 O(nlogn) 最差时间O(n^2)

    展开全文
  • 霍夫曼算法 霍夫曼编码 (Huffman coding) Huffman Algorithm was developed by David Huffman in 1951. Huffman算法由David Huffman在1951年开发。 This is a technique which is used in a data compression or it ...

    霍夫曼算法

    霍夫曼编码 (Huffman coding)

    • Huffman Algorithm was developed by David Huffman in 1951.

      Huffman算法由David Huffman在1951年开发。

    • This is a technique which is used in a data compression or it can be said that it is a coding technique which is used for encoding data.

      这是用于数据压缩的技术,或者可以说是用于编码数据的编码技术。

    • This technique is a mother of all data compression scheme.

      该技术是所有数据压缩方案的基础。

    • This idea is basically dependent upon the frequency, i.e. the frequency of the corresponding character which needs to be compressed, and by that frequency, only Huffman code will be generated.

      该思想基本上取决于频率,即,需要压缩的相应字符的频率,并且根据该频率,将仅生成霍夫曼码。

    • In case of Huffman coding, the most generated character will get the small code and least generated character will get the large code.

      对于霍夫曼编码,生成最多的字符将获得小代码,生成最少的字符将获得大代码。

    • Huffman tree is a specific method of representing each symbol.

      霍夫曼树是表示每个符号的一种特定方法。

    • This technique produces a code in such a manner that no codeword is a prefix of some other code word. These codes are called as prefix code.

      该技术以这样的方式产生代码:没有代码字是某个其他代码字的前缀。 这些代码称为前缀代码。

    霍夫曼编码算法 (Algorithm for Huffman code)

        1.	Input:-Number of message with frequency count.
        2.	Output: - Huffman merge tree.
        3.	Begin
        4.	Let Q be the priority queue,
        5.	Q= {initialize priority queue with frequencies of all symbol or message}
        6.	Repeat n-1 times 
        7.	Create a new node Z 
        8.	X=extract_min(Q)
        9.	Y=extract_min(Q)
        10.	Frequency(Z) =Frequency(X) +Frequency(y);
        11.	Insert (Z, Q)
        12.	End repeat 
        13.	Return (extract_min(Q))
        14.	End.
    
    
    

    Example:

    例:

    Let obtain a set of Huffman code for the message (m1.....m7) with relative frequencies (q1.....q7) = (4,5,7,8,10,12,20). Let us draw the Huffman tree for the given set of codes.

    让我们为消息(m1 ..... m7)获得一组霍夫曼代码,其相对频率(q1 ..... q7)=(4,5,7,8,10,12,20) 。 让我们为给定的代码集绘制霍夫曼树。

    Step 1) Arrange the data in ascending order in a table.

    步骤1)在表中按升序排列数据。

    4,5,7,8,10,12,20

    4,5,7,8,10,12,20

    Step 2) Combine first two entries of a table and by this create a parent node.

    步骤2)合并表的前两个条目,并由此创建一个父节点。

    Huffman coding algo 1

    Step 3)

    步骤3)

    A) Remove the entries 4 and 5 from the table and inert 9 at its appropriate position. 7,8,9,10,12,20

    A)从表中删除条目4和5,并在适当位置插入9。 7,8,9,10,12,20

    Combine minimum value of table and create a parent node.

    合并表的最小值并创建一个父节点。

    Huffman coding algo 2

    B) Now remove the entries 7 and 8 from the table and insert 15 at its appropriate position. 9,10,12,15,20

    B)现在从表中删除条目7和8,并在其适当位置插入15。 9,10,12,15,20

    Combine minimum value of two blocks and create a parent node.

    合并两个块的最小值并创建一个父节点。

    Huffman coding algo 3

    C) Remove the entries 9 and 10 from the table and insert 19 at its proper position. 12,15,19,20.

    C)从表中删除条目9和10,并在其适当位置插入19。 12,15,19,20。

    Combine minimum value of two blocks and create parent node.

    合并两个块的最小值并创建父节点。

    Huffman coding algo 4

    D) Remove the entries 15 and 12 from the table and insert 27 at its appropriate position. 19,20,27

    D)从桌子上取下入口15和12,并在其适当位置插入27。 19,20,27

    Combine minimum value of two blocks and create parent node.

    合并两个块的最小值并创建父节点。

    Huffman coding algo 5

    E) Remove the entries 19 and 20 from the table and insert 39 in the table. 27,39

    E)从表中删除条目19和20,然后在表中插入39。 27,39

    Combine minimum value of two blocks and create parent node.

    合并两个块的最小值并创建父节点。

    Huffman coding algo 6

    Step 4) Now assign left child as 0 and right child as 1 to encode the frequencies.

    步骤4)现在将左子级分配为0,右子级分配为1以对频率进行编码。

    Huffman coding algo 7

    Now, codes for the given frequencies are given below:

    现在,给定频率的代码如下:

    Huffman coding algo 8

    时间复杂度: (Time complexity:)

    O(nlogn) is the overall time complexity. Where n is the number of characters.

    O(nlogn)是整体时间复杂度。 其中n是字符数。

    翻译自: https://www.includehelp.com/algorithms/huffman-coding-algorithm-example-and-time-complexity.aspx

    霍夫曼算法

    展开全文
  • 时间复杂度用于度量算法的计算工作量,空间复杂度用于度量算法占用的内存空间。这篇文章主要介绍了Python算法中的时间复杂度,需要的朋友可以参考下
  • 这篇文章我们开始看看贪心算法和它的实际应用,贪心算法有很多经典的应用:哈夫曼编码、Prim和Kruskal最小生成树算法、Dijkstra单源最短路径算法 1、如何理解贪心算法 贪心算法的思想是:每次都做出当前最优的选择,...

    文章结构

    1. 如何理解贪心算法
    2. 贪心算法实例分析
    3. 使用贪心算法实现哈夫曼编码
    4. 源码地址
    5. 说明
      算法中基本的算法思想有:贪心算法、分治算法、回溯算法、动态规划。这些算法思想并不是具体的算法,他们是用来指导我们设计具体的算法和编码的算法思想。这篇文章我们开始看看贪心算法和它的实际应用,贪心算法有很多经典的应用:哈夫曼编码、Prim和Kruskal最小生成树算法、Dijkstra单源最短路径算法
      1、如何理解贪心算法
      贪心算法的思想是:每次都做出当前最优的选择,通过多步选择得出最终的最优解。它适合解决上一步的选择不会影响下一步的选择的问题。如果上一步的选择会影响下一步的选择,则使用贪心算法不一定能求出最优解。
      1.1 能够使用贪心算法求解的问题举例
      问题:假如我们有一个能够容纳100Kg物品的袋子,可以装各种物品,不管物品的体积。现在我们有5种豆子,每种豆子的总重量和总价值各不相同。那如何往背包里面装这些豆子,使得最后背包里物品的总价值最大呢?
      我们一眼就能知道这个问题的解法,先求出每种豆子的单价,然后从单价高的豆子开始装,装完单价高的,再去装次高的,直到袋子装满为止。
      这个问题就适合用贪心算法来解,实际上上面的做法体现的就是贪心算法的思想(每次都做出当前最优的选择)。这里第一步选择装单价最高的豆子之后,不会影响第二步去选择装次高的豆子的选择,同样第二步也不会影响第三步去选择单价排名第三的豆子。
      1.2 不能使用贪心算法来求解的问题举例
      问题:假如我们要在一个有权图中,从顶点S开始,找一条到顶点T的最短路径。

    贪心算法的解决思路是,每次都选择一条根当前顶点相连的权最小的边(每次都做出当前最优的选择),直到找到顶点T。按照这种思路,我们求出的最短路径是S->A->E->T,路径长度1+4+4=9;而实际的最短路径是S->B->D->T,路径长度2+2+2=6 。
    为什么这里贪心算法得不到最优解呢?我们第一步从S->A和第一步从S->B,下一步面对的顶点和边是不一样的。也就是我们前面的选择会影响后面的选择,所以得不出最优解。
    2、贪心算法实例分析
    接下来,我们再看几个能够使用贪心算法求最优解的问题。
    2.1 分糖果
    假设我们有m个糖果和n个小孩,糖果的个数比小孩的个数少,糖果的重量不等,每个小孩对糖果大小的需求也不同,问如何分别糖果能尽可能满足最多数量的孩子的需求。
    我们用贪心算法怎么来解决这个问题呢?我们先用最小的糖果来满足对糖果需求最小的孩子的需求,然后再去从剩下的糖果中找最小的糖果满足需求次小的孩子,按照这个思路,直到没有糖果可以满足小孩的需求了为止。
    2.2 钱币找零
    假设我们有1元、2元、5元、10元、20元、50元、100元面额的纸币各对应c1、c2、c5、c10、c20、c50、c100张。当我们要支付k元的时候,我们如何支付,使得使用的钱币数量最小。
    我们用贪心算法怎么来解决这个问题呢?先用面额大,然后在用面额小一点的,依次类推,最后剩下的用1元来补
    2.3 求一个非负数移除K个数字之后的最小值
    在一个非负数a中,我们希望从中移除k个数字,让剩下的数字值最小,如何选择移除哪k个数字呢?
    使用贪心算法来求解这个问题?每一次移除都使当前的数字是能得到的最小值:从高位开始,和低一位的数字比较,如果高位大,则移除高位,如果地位大,则拿着地位和后面的继续比较,直到高位大于低位时,移除高位。移除k个数就重复这个过程k次。
    3、使用贪心算法实现哈夫曼编码
    3.1 什么是哈夫曼编码
    哈夫曼编码是一种十分有效的编码方法,广泛应用于数据压缩中,其压缩率通常在20%~90%之间。哈夫曼编码通过采用不等长的编码方式,根据字符频率的不同,选择不同长度的编码,对频率越高的字符采用越短的编码实现数据的高度压缩。这种对频率越高的字符采用越短的编码来编码的方式应用的就是贪心算法的思想。
    哈夫曼编码具体是什么呢?我们采用一个实例来具体看一下。
    假如我们有一个包含1000个字符的文件,每个字符占1个byte(1byte=8bits),则存储这100个字符一共需要8000bits,是否有更节省空间的存储方式呢?
    如果我们统计一下这1000个字符中总共有多少种字符,原来需要8bit是来表示一个字符,我们使用更少的位数来表示这些字符,则可以减少存储空间。假设这1000个字符中总共有a、b、c、d、e、f共6种字符,则我们只需要使用3个二进制位来表示,那存储这1000个字符就只需要3000bits,比原来更节省存储空间。
    a(000)、b(001)、c(010)、d(011)、e(100)、f(101)
    有没有比这种方式更节省存储空间的编码方式呢?那就是哈夫曼编码,哈夫曼编码是怎么编码的呢?它会根据字符出现的频率给与字符不等长的编码,频率越高的字符编码越短,频率越高的字符编码越长。当然它不能像等长编码一样直接按固定长度去读取二进制位,翻译成字符,为了能够准确读取翻译字符,它要求一个字符的编码不能是另外一个字符的前缀。
    假设a、b、c、d、e、f这6个字符出现的频率依次降低,则我们可以给与他们这样的编码
    a(1)、b(01)、c(001)、d(0001)、e(00001)、f(00000)
    字符频率和编码,每种字符需要的总的存储位数如图,我们可以看到使用哈夫曼编码来存储这1000个字符只需要2100bits,相同的方式下,比等长bit压缩更节省空间了。

    哈夫曼编码的思想不难理解,但是我们如何根据字符出现的频率的不同,给不同的字符进行不同长度的编码呢?
    3.2 哈夫曼编码实现过程
    哈夫曼编码的实现过程如下:

    1. 将每个字符看做一个节点,以频率的大小作为权重,将所有的字符放到优先级队列中
    2. 从优先级队列中取两个权重最小的节点,创建一个新的节点作为他们的父节点,父节点的权重为两个字节的权重之和,然后将父节点插入优先级队列中。然后再从优先级队列中取出两个权重最小的节点,创建一个他们的父节点,权重等于两个子节点之和,并插入优先级队列中。重复这个过程直到优先级队列中只有一个节点为止。
    3. 优先级队列中只有一个节点的时候,哈夫曼树就创建好了,所有的字符对应的节点都在这颗哈夫曼树的叶子结点上,然后我们开始编码,从根节点开始,指向左子节点的边,我们统统标记为0,指向右子节点的边,我们通过标记为1,从根节点到叶子节点的路径就是叶子节点对应的哈夫曼编码
      上面的例子的计算编码的过程图示如下:

    构建哈夫曼树的过程

    计算编码的过程
    3.2 代码实现

    1. 构建哈夫曼树

    2. 获取哈夫曼编码

    3. 将编码转换成字符串
      public class HuffmanTree {
      /**

      • 创建哈夫曼树
      • @param list
      • @param
      • @return
        */
        public static Node createTree(List<Node> list) {
        if (list == null) {
        return null;
        }
        PriorityQueue queue = new PriorityQueue<>();
        for (int i = 0; i < list.size(); i++) {
        queue.add(list.get(i));
        }
        while (queue.size() > 1) {
        Node left = queue.poll();
        Node right = queue.poll();
        Node node = new Node(left.pow + right.pow, left, right);
        queue.add(node);
        }
        return queue.poll();
        }

      /**

      • 获取哈夫曼编码(编码这里使用字符串表示)
      • @param node
      • @param
      • @return
        */
        public static Map<T, String> getCode(Node node) {
        if (node == null) {
        return null;
        }
        Map<T, String> map = new HashMap<>();
        if (node.left != null && node.left != null) {
        List codes = new ArrayList<>();
        traverse(node, map, codes);
        } else {
        map.put(node.item, “0”);
        }
        return map;
        }

      private static void traverse(Node node, Map<T, String> map, List codes) {
      if (node.left == null && node.right == null) {
      StringBuilder builder = new StringBuilder();
      for (int i = 0; i < codes.size(); i++) {
      builder.append(codes.get(i));
      }
      map.put(node.item, builder.toString());
      }
      //左子树
      if (node.left != null) {
      codes.add(“0”);
      traverse(node.left, map, codes);
      codes.remove(codes.size() - 1);
      }
      //右子树
      if (node.right != null) {
      codes.add(“1”);
      traverse(node.right, map, codes);
      codes.remove(codes.size() - 1);
      }
      }

      /**

      • 根据哈夫曼编码,解析出字符串
      • @param map
      • @param codeStr
      • @param
      • @return
        */
        public static String reCode(Map<T, String> map, String codeStr) {
        if (map == null) {
        return “”;
        }
        //将key和value倒过来
        Map<String, T> map2 = new HashMap<>();
        for (T key : map.keySet()) {
        map2.put(map.get(key), key);
        }
        StringBuilder builder = new StringBuilder();
        while (codeStr.length() > 0) {
        for (String key : map2.keySet()) {
        if (codeStr.startsWith(key)) {
        builder.append(map2.get(key));
        codeStr = codeStr.replaceFirst(key, “”);
        break;
        }
        }
        }
        return builder.toString();
        }

      public static class Node implements Comparable {
      T item;
      int pow;
      Node left;
      Node right;

      public Node() {
      }
      
      public Node(T item, int pow) {
          this.item = item;
          this.pow = pow;
      }
      
      public Node(int pow, Node<T> left, Node<T> right) {
          this.pow = pow;
          this.left = left;
          this.right = right;
      }
      
      @Override
      public int compareTo(Node o) {
          return pow - o.pow;
      }
      

      }
      }
      测试
      /**

    • 验证编码与反编码
      */
      @Test
      public void test2() {
      int size = 20;
      //创建原始的数据
      char[] chars = getChars(size);
      //统计字符出现的频率,构建字符节点
      List<HuffmanTree.Node> list = getNodes(size, chars);
      print(list, " org node:");
      //创建哈夫曼树
      HuffmanTree.Node root = HuffmanTree.createTree(list);
      //获取哈夫曼编码(这里以字符串表示二进制)
      Map<Character, String> codeMap = HuffmanTree.getCode(root);
      print(codeMap, “node code:”);
      //输出原始数据
      System.out.println(" orgStr:" + new String(chars));
      //编码原始数据
      StringBuilder codeBuilder = new StringBuilder();
      for (int i = 0; i < size; i++) {
      Character ch = chars[i];
      codeBuilder.append(codeMap.get(ch));
      }
      String codeStr = codeBuilder.toString();
      System.out.println(“code:” + codeStr);
      //解析编码
      String reCodeStr = HuffmanTree.reCode(codeMap, codeStr);
      System.out.println(“recodeStr:” + reCodeStr);
      }
    展开全文
  • 哈夫曼编码 一、【问题描述】 设要编码的字符集为{d1,d2,…,dn},它们出现的频率为{w1,w2,…,wn},应用哈夫曼树构造最优的不等长的由0,1构成的编码方案。 二、【问题求解】 先构建以这个n个结点为叶子结点的哈夫曼...

    哈夫曼编码

    一、【问题描述】
    设要编码的字符集为{d1,d2,…,dn},它们出现的频率为{w1,w2,…,wn},应用哈夫曼树构造最优的不等长的由0,1构成的编码方案。

    二、【问题求解】
    先构建以这个n个结点为叶子结点的哈夫曼树,然后由哈夫曼树产生各叶子结点对应字符的哈夫曼编码。

    (0)哈夫曼树:给定n个权值作为n个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树。

    (1) 路径和路径长度:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。

    (2) 结点的权及带权路径长度:若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。

    (3) 树的带权路径长度:树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL。

    ⭐对于一些基本概念,此处不进行更多赘述
    如果还有疑惑可以参考这篇博文:
    传送门→_→ 哈夫曼树+哈夫曼编码

    构造一棵哈夫曼树的方法如下:
    ①由给定的n个权值, n个权值分别设为 w1、w2、…、wn,构造n棵只有1个叶子结点的二叉树,从而得到一个二叉树的集合F={T1,T2,…Tn}。

    ②在F中选取根节点的权值最小和次小的两颗二叉树作为左、右子树构造一棵新的二叉树,这颗新的二叉树根节点的权值为其左、右子树根节点权值之和。即合并两棵二叉树为一棵二叉树。

    ③重复步骤②,当F中只剩下一棵二叉树时,这棵二叉树便是所要建立的哈夫曼树。

    例如给定a~d四个字符,它们的权值集合为w={100,10,50,20}

    首先构造出哈夫曼树,过程如下图:
    在这里插入图片描述
    在这里插入图片描述
    接下来对字符进行编码并求出WPL
    在这里插入图片描述

    三、【代码实现】
    如下:

    #pragma warning(disable:4786) //用于屏蔽标识符过长导致的warning 
    #include <iostream>
    #include <queue>
    #include <vector>
    #include <string>
    #include <map>
    using namespace std; 
    #define MAX 101
    int n;
    struct HTreeNode				//哈夫曼树结点类型
    {
    	char data;					//字符
    	int weight;					//权值
    	int parent;					//双亲的位置
    	int lchild;					//左孩子的位置
    	int rchild;					//右孩子的位置
    };
    HTreeNode ht[MAX];				//哈夫曼树
    map<char,string> htcode;			//哈夫曼编码
    
    struct NodeType		//优先队列结点类型
    {
    	int no;				//对应哈夫曼树ht中的位置
    	char data;			//字符
    	int  weight;		//权值
    	bool operator<(const NodeType &s) const
    	{					//运算符重载进行从小到大的递增排序 
    		return s.weight<weight;
    	}
    };
    void CreateHTree()						//构造哈夫曼树
    {
    	NodeType e,e1,e2;
    	priority_queue<NodeType> qu;
    	for (int k=0;k<2*n-1;k++)	//设置所有结点的指针域
    		ht[k].lchild=ht[k].rchild=ht[k].parent=-1;
    	for (int i=0;i<n;i++)				//将n个结点进队qu
    	{
    		e.no=i;
    		e.data=ht[i].data;
    		e.weight=ht[i].weight;
    		qu.push(e);
    	}
    	for (int j=n;j<2*n-1;j++)			//构造哈夫曼树的n-1个非叶结点
    	{
    		e1=qu.top();  qu.pop();		//出队权值最小的结点e1
    		e2=qu.top();  qu.pop();		//出队权值次小的结点e2
    		ht[j].weight=e1.weight+e2.weight; //构造哈夫曼树的非叶结点j	
    		ht[j].lchild=e1.no;
    		ht[j].rchild=e2.no;
    		ht[e1.no].parent=j;			//修改e1.no的双亲为结点j
    		ht[e2.no].parent=j;			//修改e2.no的双亲为结点j
    		e.no=j;						//构造队列结点e
    		e.weight=e1.weight+e2.weight;
    		qu.push(e);
    	}
    }
    void CreateHCode()			//构造哈夫曼编码
    {
    	string code;
    	code.reserve(MAX);
    	for (int i=0;i<n;i++)	//构造叶结点i的哈夫曼编码
    	{
    		code="";
    		int curno=i;
    		int f=ht[curno].parent;
    		while (f!=-1)				//循环到根结点
    		{
    			if (ht[f].lchild==curno)	//curno为双亲f的左孩子
    				code='0'+code;
    			else					//curno为双亲f的右孩子
    				code='1'+code;
    			curno=f; f=ht[curno].parent;
    		}
    		htcode[ht[i].data]=code;	//得到ht[i].data字符的哈夫曼编码
    	}
    }
    void DispHCode()					//输出哈夫曼编码
    {
    	map<char,string>::iterator it;
    	for (it=htcode.begin();it!=htcode.end();++it)
    		cout << "    " << it->first << ": " << it->second <<	endl;
    }
    void DispHTree()					//输出哈夫曼树
    {
    	for (int i=0;i<2*n-1;i++)
    	{
    		printf("    data=%c, weight=%d, lchild=%d, rchild=%d, parent=%d\n",
    			ht[i].data,ht[i].weight,ht[i].lchild,ht[i].rchild,ht[i].parent);
    	}
    }
    int WPL()				//求WPL
    {
    	int wps=0;
    	for (int i=0;i<n;i++)
    		wps+=ht[i].weight*htcode[ht[i].data].size();
    	return wps;
    }
    
    int main()
    {
    	n=4;
    	ht[0].data='a'; ht[0].weight=100;		//置初值即n个叶子结点
    	ht[1].data='b'; ht[1].weight=10;  
    	ht[2].data='c'; ht[2].weight=50;  
    	ht[3].data='d'; ht[3].weight=20;  
    	CreateHTree();					//建立哈夫曼树
    	printf("构造的哈夫曼树:\n");
    	DispHTree();
    	CreateHCode();					//求哈夫曼编码
    	printf("产生的哈夫曼编码如下:\n");
    	DispHCode();					//输出哈夫曼编码
    	printf("WPL=%d\n",WPL());
    	return 0;
    }
    

    代码运行截图:
    在这里插入图片描述
    本文参考自《算法设计与分析》李春葆第二版

    展开全文
  • 贪心算法哈夫曼编码问题

    万次阅读 2018-03-04 03:09:45
    1、问题通常的编码方法有固定长度编码和不等长度编码两种。这是一个设计最优编码方案的问题,目的是使总码长度最短。这个问题利用字符的使用频率来编码,是不等长编码方法,使得经常使用的字符编码较短,不常使用的字符...
  • 贪心算法哈夫曼编码

    千次阅读 多人点赞 2018-10-28 14:15:45
    贪心算法哈夫曼编码 1.最优二叉树:(哈夫曼树) 1&gt;结点的权:赋予叶子结点以个有意义的值; 2&gt;结点的路径长度:从根结点到当前结点的的长度 结点的带权路径长度:W*L (W:权 L:路径长度) ...
  • 时间复杂度和空间复杂度是用来评价算法效率高低的2个标准。 时间复杂度:就是说执行算法需要消耗的时间长短,越快越好。比如for循环次数。 空间复杂度:就是说执行当前算法需要消耗的存储空间大小,也是越少越好。...
  • Huffman编码(哈夫曼编码),

    千次阅读 2015-12-13 16:27:22
    实现Huffman编码是用贪心算法来实现的,。实现Huffman最好的数据结构时优先级队列。整个算法的时间复杂度可以达到nlg(n),这里为了简单,没有实现最小堆,而使用的是STL中的set,通过实现正确的比较函数对象,每次...
  • 构造最优前缀码的贪心算法就是哈夫曼算法 pop:pop:pop: 每次从队列中取出两个权值最小的节点当作孩子节点 push:push:push: 根据 poppoppop 操作取出的两个子结点,构成一个带有新的权值(两个子结
  • 介绍贪心算法的一般步骤: 1.建立数学模型来描述问题。 2.把求解的问题分成若干个子问题。 3.对每一子问题求解,得到子问题的局部最优解。 4.把子问题的解局部最优解合成原来解问题的一个解。 二. 贪心算法适合解决...
  • 实现Huffman编码

    2011-09-01 23:33:18
    HUFFMAN编码又称哈夫曼编码,是一种可变长编码方式,是由美国数学家David Huffman创立的,是二叉树的一种特殊转化形式。编码的原理是:将使用次数多的代码转换成长度较短的代码,而使用次数少的可以使用较长的编码,...
  • 哈夫曼树、哈夫曼编码详解

    千次阅读 多人点赞 2021-06-17 09:33:06
    哈夫曼树、哈夫曼编码,也就这么一回事,一文搞懂!
  • 为此提出一种新的自适应哈夫曼编码算法,它利用符号到达前后构造哈夫曼树的相似性,仅更新少量节点即可完成编码过程 。与原有的 V算法相比,有效降低了编码复杂度,占用存储资源较少,易于硬件实现 。
  • 【贪心算法哈夫曼编码问题

    千次阅读 多人点赞 2020-05-09 21:47:11
    哈夫曼编码算法用字符在文件中出现的频率表来建立一个用0,1串表示各字符的最优表示方式。一个包含100,000个字符的文件,各字符出现频率不同,设某信源产生a,b,c,d和f 6种符号,其频率见下表,单位为千次。 从表...
  • 代码 #include<iostream> #include <string> #include <queue> #include <utility> #include<cstring> #include<stdlib.h> #include <algorithm>... ...
  • 举例理解哈夫曼树与哈夫曼编码

    万次阅读 2020-07-02 08:52:56
    举例理解哈夫曼树,C语言实现哈夫曼
  • 1、问题参考我的博客:贪心算法哈夫曼编码问题 2、优先队列知识复习参考我的博客: C++之STL之priority_queue 3、代码实现#include &lt;iostream&gt; #include &lt;queue&gt; using namespace ...
  • } } 哈夫曼编码: 如何编码: 哈夫曼编码代码实现(编码和解码): import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import...
  • 贪心算法 - 哈夫曼编码 Huffman

    千次阅读 2017-02-20 15:07:36
    贪心算法 - 哈夫曼编码 Huffman哈夫曼编码: 一种字符编码方式,常用于数据文件压缩。压缩率通常在20%~90%。 主要思想: 采取可变长编码方式,对文件中出现次数多的字符采取比较短的编码,对于出现次数少的字符...
  • 哈夫曼编码 问题描述: 代码(码字):Q{001,00,010,01}表示字符a,b,c,d 同一序列:0100001 产生两种译码(产生歧义):01 00 001;010 00 01 二元前缀码:任何字符的代码不能作为其他字符代码的前缀 利用二元...
  • 哈夫曼编码-贪心算法

    千次阅读 2019-03-30 18:50:48
    哈夫曼编码的基本思想时以字符的使用频率作为权构建一颗哈夫曼树,然后利用哈夫曼树对字符进行编码。构造一颗哈夫曼树,是将所有的编码的字符作为叶子结点,该字符在文件中的使用频率作为叶子结点的权值,以自底向上...
  • 贪心法求解哈夫曼编码问题

    千次阅读 2020-03-22 10:42:49
    先构建以这个n个结点为叶子结点的哈夫曼树,然后由哈夫曼树产生各叶子结点对应字符的哈夫曼编码。 哈夫曼树(Huffman Tree)的定义:设二叉树具有n个带权值的叶子结点,从根结点到每个叶子结点都有一个路径长度。从...
  • #include<...#define maxsize 100 //哈夫曼编码的最大位数 typedef struct { char ch; float weight; int lchild,rchild,parent; }hufmtree; typedef struct { char bits[n]; //位串 int start;
  • 时间复杂度(一)

    2018-08-25 16:15:41
    二叉查找树——时间复杂度logN(N总数) 高度初值1 深度初值0   AVL高度平衡树 红黑树插入N个——时间复杂度NlogN 哈夫曼树,权值大的靠近根。应用于变长编码表中...
  • 贪心算法-(哈夫曼编码)HuffmanCode

    千次阅读 2017-08-19 11:58:44
    哈夫曼编码应用在于对于文件的压缩,压缩效率是非常的高。实现哈夫曼编码,得首先知道哈夫曼树的形成过程是怎样进行的: 1、对于所要编码的数据,首先得将它们中找到其中的最小的两个位置合并成一个小树,节点的权值...
  • 0023算法笔记——【贪心算法哈夫曼编码问题

    万次阅读 多人点赞 2013-03-26 19:22:21
    哈夫曼编码算法用字符在文件中出现的频率表来建立一个用0,1串表示各字符的最优表示方式。一个包含100,000个字符的文件,各字符出现频率不同,如下表所示。  有多种方式表示文件中的信息,若用0,1码表示字符的...

空空如也

空空如也

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

哈夫曼编码算法复杂度