Построение дерева "Код Хаффмана" - C#

Узнай цену своей работы

Формулировка задачи:

Доброго времени суток, есть коллекция символов с числом их повторений, как реализовать этот шаг:
Выбираются два свободных узла дерева с наименьшими весами. Создается их родитель с весом, равным их суммарному весу. <- Этот интересует
Если я правильно понимаю, коллекция состоит, например: h - 1, e - 1, o - 1, l - 2. Берутся первые два символа объединяются и в итоге получается след.: he - 2, o - 1, l - 2, и так до тех пор пока не останется одна ячейка: helo - 5. Дальше встает вопрос,что каждому символу необходима присвоить значение 1 или 0,когда это делать?
Кто-нибудь подскажет?

Решение задачи: «Построение дерева "Код Хаффмана"»

textual
Листинг программы
  1.  public class HuffmanTree
  2.     {
  3.         private List<Node> nodes = new List<Node>();
  4.         public Node Root { get; set; }
  5.         public Dictionary<char, int> Frequencies = new Dictionary<char, int>();
  6.  
  7.         public void Build(string source)
  8.         {
  9.             for (int i = 0; i < source.Length; i++)
  10.             {
  11.                 if (!Frequencies.ContainsKey(source[i]))
  12.                 {
  13.                     Frequencies.Add(source[i], 0);
  14.                 }
  15.  
  16.                 Frequencies[source[i]]++;
  17.             }
  18.  
  19.             foreach (KeyValuePair<char, int> symbol in Frequencies)
  20.             {
  21.                 nodes.Add(new Node() { Symbol = symbol.Key, Frequency = symbol.Value });
  22.             }
  23.  
  24.             while (nodes.Count > 1)
  25.             {
  26.                 List<Node> orderedNodes = nodes.OrderBy(node => node.Frequency).ToList<Node>();
  27.  
  28.                 if (orderedNodes.Count >= 2)
  29.                 {
  30.                     // Take first two items
  31.                     List<Node> taken = orderedNodes.Take(2).ToList<Node>();
  32.  
  33.                     // Create a parent node by combining the frequencies
  34.                     Node parent = new Node()
  35.                     {
  36.                         Symbol = '*',
  37.                         Frequency = taken[0].Frequency + taken[1].Frequency,
  38.                         Left = taken[0],
  39.                         Right = taken[1]
  40.                     };
  41.  
  42.                     nodes.Remove(taken[0]);
  43.                     nodes.Remove(taken[1]);
  44.                     nodes.Add(parent);
  45.                 }
  46.  
  47.                 this.Root = nodes.FirstOrDefault();
  48.  
  49.             }
  50.  
  51.         }
  52.  
  53.         public BitArray Encode(string source)
  54.         {
  55.             List<bool> encodedSource = new List<bool>();
  56.  
  57.             for (int i = 0; i < source.Length; i++)
  58.             {
  59.                 List<bool> encodedSymbol = this.Root.Traverse(source[i], new List<bool>());
  60.                 encodedSource.AddRange(encodedSymbol);
  61.             }
  62.  
  63.             BitArray bits = new BitArray(encodedSource.ToArray());
  64.  
  65.             return bits;
  66.         }
  67.  
  68.         public string Decode(BitArray bits)
  69.         {
  70.             Node current = this.Root;
  71.             string decoded = "";
  72.  
  73.             foreach(bool bit in bits){
  74.                 if (bit)
  75.                 {
  76.                     if (current.Right != null)
  77.                     {
  78.                         current = current.Right;
  79.                     }
  80.                 }
  81.                 else
  82.                 {
  83.                     if(current.Left != null)
  84.                     {
  85.                         current = current.Left;
  86.                     }
  87.                 }
  88.  
  89.                 if (IsLeaf(current))
  90.                 {
  91.                     decoded += current.Symbol;
  92.                     current = this.Root;
  93.                 }
  94.             }
  95.  
  96.             return decoded;
  97.         }
  98.  
  99.         public bool IsLeaf(Node node)
  100.         {
  101.             return (node.Left == null && node.Right == null);
  102.         }
  103.  
  104.     }
  105.  
  106. public class Node
  107.     {
  108.         public char Symbol { get; set; }
  109.         public int Frequency { get; set; }
  110.         public Node Right { get; set; }
  111.         public Node Left { get; set; }
  112.  
  113.         public List<bool> Traverse(char symbol,List<bool> data)
  114.         {
  115.             // Leaf
  116.             if (Right == null && Left == null)
  117.             {
  118.                 if (symbol.Equals(this.Symbol))
  119.                 {
  120.                     return data;
  121.                 }
  122.                 else
  123.                 {
  124.                     return null;
  125.                 }
  126.             }
  127.             else
  128.             {
  129.                 List<bool> left = null;
  130.                 List<bool> right = null;
  131.  
  132.                 if (Left != null)
  133.                 {
  134.                     List<bool> leftPath = new List<bool>();
  135.                     leftPath.AddRange(data);
  136.                     leftPath.Add(false);
  137.  
  138.                     left = Left.Traverse(symbol, leftPath);
  139.                 }
  140.  
  141.                 if (Right != null)
  142.                 {
  143.                     List<bool> rightPath = new List<bool>();
  144.                     rightPath.AddRange(data);
  145.                     rightPath.Add(true);
  146.                     right = Right.Traverse(symbol, rightPath);
  147.                 }
  148.  
  149.                 if (left != null)
  150.                 {
  151.                     return left;
  152.                 }
  153.                 else
  154.                 {
  155.                     return right;
  156.                 }
  157.             }
  158.         }
  159.     }
  160.  
  161. class Program
  162.     {
  163.         static void Main()
  164.         {
  165.             HuffmanTree huffmanTree = new HuffmanTree();
  166.             string input;
  167.  
  168.             using (StreamReader fileIn = new StreamReader(@""))
  169.             {
  170.                 input = fileIn.ReadToEnd();
  171.             }
  172.  
  173.             huffmanTree.Build(input);
  174.             BitArray encoded = huffmanTree.Encode(input);
  175.  
  176.             string decoded = huffmanTree.Decode(encoded);
  177.             Console.WriteLine("Decoded: " + decoded);
  178.            
  179.  
  180.               Console.Write("Encoded: ");
  181.               using (StreamWriter file =
  182.                                 new StreamWriter(@""))
  183.                 {
  184.                 foreach (bool bit in encoded)
  185.                      {
  186.                         file.Write((bit? 1 : 0) + "");
  187.                         Console.Write((bit ? 1 : 0) + "");
  188.                       }
  189.                      Console.WriteLine();
  190.  
  191.                  }
  192.         }
  193.     }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

9   голосов , оценка 3.667 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут