c# 使用优先级队列的霍夫曼编码(Huffman Coding using Priority Queue)

先决条件: 贪婪算法 |  (霍夫曼编码)、priority_queue::push() 和 C++ STL 中的 priority_queue::pop() 。

贪婪算法 |  (霍夫曼编码):

C#:C# 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)-CSDN博客

JavaScript:JavaScript 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)-CSDN博客

python:python 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)-CSDN博客 

java:java 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)-CSDN博客 

c++ STL:c++ STL 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)-CSDN博客 

c++:c++ 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)_霍夫曼的贪婪算法设计核心代码-CSDN博客 

c语言:c语言 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)_霍夫曼的贪婪c语言-CSDN博客 

priority_queue::push() 和 C++ STL 中的 priority_queue::pop() :

C++ STL 中的 priority_queue::push() 和 priority_queue::pop()-CSDN博客

        给定一个字符数组 ch[]和每个字符的频率作为freq[] 。任务是使用优先级队列为ch[]中的每个字符找到霍夫曼编码。

例子 

输入: ch[] = { 'a', 'b', 'c', 'd', 'e', 'f' }, freq[] = { 5, 9, 12, 13, 16, 45 } 
输出: 
f 0 
c 100 
d 101 
a 1100 
b 1101 
e 111 

方法: 

    1、将ch[]中所有映射到相应频率freq[]的字符推入优先级队列。
    
    2、要创建哈夫曼树,请从优先级队列中弹出两个节点。
    
    3、将从优先级队列中弹出的两个节点指定为新节点的左子节点和右子节点。
    
    4、将新形成的节点推送到优先级队列中。
    
    5、重复以上所有步骤,直到优先级队列的大小变为 1。
    
    6、遍历哈夫曼树(其根是优先级队列中剩下的唯一节点)以存储哈夫曼代码
    
    7、打印ch[]中每个字符的所有存储的哈夫曼编码。 

下面是上述方法的实现: 

using System;
using System.Collections.Generic;
 
public class HuffmanTreeNode
    : IComparable<HuffmanTreeNode> {
    public char Data
    {
        get;
        set;
    }
    public int Freq
    {
        get;
        set;
    }
    public HuffmanTreeNode Left
    {
        get;
        set;
    }
    public HuffmanTreeNode Right
    {
        get;
        set;
    }
 
    public HuffmanTreeNode(char character, int frequency)
    {
        Data = character;
        Freq = frequency;
        Left = Right = null;
    }
 
    public int CompareTo(HuffmanTreeNode other)
    {
        return Freq - other.Freq;
    }
}
 
public class GFG {
    // Maximum Height of Huffman Tree.
    private const int MaxSize = 100;
 
    // Function to print the huffman code for each
    // character. It uses arr to store the codes
    private static void PrintCodes(HuffmanTreeNode root,
                                   int[] arr, int top)
    {
        // Assign 0 to the left node and recur
        if (root.Left != null) {
            arr[top] = 0;
            PrintCodes(root.Left, arr, top + 1);
        }
 
        // Assign 1 to the right node and recur
        if (root.Right != null) {
            arr[top] = 1;
            PrintCodes(root.Right, arr, top + 1);
        }
 
        // If this is a leaf node, then we print root.Data
        // We also print the code for this character from
        // arr
        if (root.Left == null && root.Right == null) {
            Console.Write(root.Data + " ");
            for (int i = 0; i < top; ++i) {
                Console.Write(arr[i]);
            }
            Console.WriteLine();
        }
    }
 
    // Function to generate Huffman Encoding Tree
    private static HuffmanTreeNode
    GenerateTree(SortedList<int, HuffmanTreeNode> list)
    {
        // We keep on looping till only one node remains in
        // the SortedList
        while (list.Count != 1) {
            // Node which has least frequency
            HuffmanTreeNode left = list.Values[0];
            list.RemoveAt(0);
 
            // Node which has least frequency
            HuffmanTreeNode right = list.Values[0];
            list.RemoveAt(0);
 
            // A new node is formed with frequency left.Freq
            // + right.Freq We take data as '$' because we
            // are only concerned with the frequency
            HuffmanTreeNode node = new HuffmanTreeNode(
                '$', left.Freq + right.Freq);
            node.Left = left;
            node.Right = right;
 
            // Add the new node back to the SortedList
            list.Add(node.Freq, node);
        }
 
        return list.Values[0];
    }
 
    // Function to generate Huffman Codes
    public static void HuffmanCodes(char[] data, int[] freq,
                                    int size)
    {
        // Declaring SortedList using custom comparer
        SortedList<int, HuffmanTreeNode> list
            = new SortedList<int, HuffmanTreeNode>();
 
        // Populating the SortedList
        for (int i = 0; i < size; i++) {
            HuffmanTreeNode newNode
                = new HuffmanTreeNode(data[i], freq[i]);
            list.Add(freq[i], newNode);
        }
 
        // Generate Huffman Encoding Tree and get the root
        // node
        HuffmanTreeNode root = GenerateTree(list);
 
        // Print Huffman Codes
        int[] arr = new int[MaxSize];
        int top = 0;
        PrintCodes(root, arr, top);
    }
 
    // Driver Code
    public static void Main(string[] args)
    {
        char[] data = { 'a', 'b', 'c', 'd', 'e', 'f' };
        int[] freq = { 5, 9, 12, 13, 16, 45 };
        int size = data.Length;
 
        // Function call
        HuffmanCodes(data, freq, size);
    }

输出: 
f 0 
c 100 
d 101 
a 1100 
b 1101 
e 111
 

时间复杂度: O(n*logn),其中 n 是唯一字符的数量
辅助空间: O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值