public static HuffmanNode HuffmanNode_Create(HuffmanNode other)
 {
     return(new HuffmanNode
     {
         Character = other.Character,
         Frequency = other.Frequency,
         Left = other.Left != null
         ? HuffmanNode_Create(other.Left)
         : null,
         Right = other.Right != null
         ? HuffmanNode_Create(other.Right)
         : null,
     });
 }
        // Etap III

        /// <summary>
        /// Metoda dokonuje dekompresji tekstu skompresowanego metodą Huffmana
        /// </summary>
        /// <param name="root">Drzewo Huffmana wykorzystywane do dekompresji</param>
        /// <param name="encoding">Skompresowany tekst</param>
        /// <returns>Odtworzony tekst</returns>
        public string Decompress(HuffmanNode root, BitArray encoding)
        {
            if (root == null || encoding == null || encoding.Length == 0)
            {
                throw new ArgumentNullException("invalid inputs");
            }

            encoderedString = new StringBuilder();
            if (root.Left == null && root.Right == null && encoding.Cast <bool>().Any(x => x == true))
            {
                throw new ArgumentException("incorrect encoding");
            }

            Decode(root, root, encoding, 0);
            return(encoderedString.ToString());
        }
        private string AssertNoDuplicatedCharacters(HuffmanNode root)
        {
            var visitedCharacters = new SortedSet <char>();

            return(NodeVisitor(root, node =>
            {
                if (node.Character > 0)
                {
                    if (visitedCharacters.Contains(node.Character))
                    {
                        return $"{root.Character} was encountered more than once in huffman tree";
                    }
                    visitedCharacters.Add(node.Character);
                }
                return null;
            }));
        }
        private string AssertNoCircularReferences(HuffmanNode root)
        {
            var visitedNodes = new List <HuffmanNode>();

            return(NodeVisitor(root, node =>
            {
                string errorMessage = null;
                visitedNodes.ForEach(visitedNode =>
                {
                    if (ReferenceEquals(visitedNode, node))
                    {
                        errorMessage = "Huffman tree contains circular references";
                    }
                });
                visitedNodes.Add(node);
                return errorMessage;
            }));
        }
 public static bool HuffmanNode_Equals(HuffmanNode lhs, HuffmanNode rhs)
 {
     if (lhs == null && rhs == null)
     {
         return(true);
     }
     if (lhs != null && rhs != null)
     {
         if (lhs.Character != rhs.Character)
         {
             return(false);
         }
         if (lhs.Frequency != rhs.Frequency)
         {
             return(false);
         }
         return(HuffmanNode_Equals(lhs.Left, rhs.Left) && HuffmanNode_Equals(lhs.Right, rhs.Right));
     }
     return(false);
 }
        private string AssertOnlyBaseTextCharacters(HuffmanNode root)
        {
            bool[] characters = new bool[char.MaxValue];

            foreach (char character in baseText)
            {
                characters[character] = true;
            }

            return(NodeVisitor(root, node =>
            {
                if (node.Character > 0)
                {
                    if (!characters[node.Character])
                    {
                        return $"Huffman tree should contains only characters that were in base text";
                    }
                }
                return null;
            }));
        }
 private string AssertTreeStructure(HuffmanNode root)
 {
     return(NodeVisitor(root, node =>
     {
         if (node.Frequency <= 0)
         {
             return "Node should have positive frequency";
         }
         if (node.Character == 0)
         {
             if (node.Left == null)
             {
                 return "Non-terminating node (character==0) should have left descendant";
             }
             if (node.Right == null)
             {
                 return "Non-terminating node (character==0) should have right descendant";
             }
             if (node.Frequency != node.Right.Frequency + node.Left.Frequency)
             {
                 return "Non-terminating node (character==0) should have frequency equal to sum of descendant frequencies";
             }
         }
         else
         {
             if (node.Left != null)
             {
                 return $"Leaf node (character='{node.Character}')  should not have left descendant";
             }
             if (node.Right != null)
             {
                 return $"Leaf node (character='{node.Character}') should not have right descendant";
             }
         }
         return null;
     }));
 }
        /// <summary>
        /// Metoda tworzy drzewo Huffmana dla zadanego tekstu
        /// </summary>
        /// <param name="baseText">Zadany tekst</param>
        /// <returns>Drzewo Huffmana</returns>
        public HuffmanNode CreateHuffmanTree(string baseText)
        {
            if (baseText == null || baseText.Length == 0)
            {
                throw new ArgumentNullException("invalid string");
            }

            var counter = Counter(baseText);

            HuffmanPriorityQueue pq = new HuffmanPriorityQueue();

            //var orderedCount = counter.OrderBy(x => x.Value);
            foreach (var c in counter)
            {
                var hn = new HuffmanNode();
                hn.Character = c.Key;
                hn.Frequency = c.Value;
                hn.Left      = null;
                hn.Right     = null;
                pq.Put(hn);
            }

            while (pq.Count > 1)
            {
                var t1 = pq.Get();
                var t2 = pq.Get();

                var hn = new HuffmanNode();
                hn.Frequency = t1.Frequency + t2.Frequency;
                hn.Left      = t1;
                hn.Right     = t2;
                pq.Put(hn);
            }

            return(pq.Get());
        }
 private HuffmanNode[] DefineSampleTrees() // 5 drzew
 {
     HuffmanNode[] _trees = new HuffmanNode[] {
         new HuffmanNode
         {
             Frequency = 42,
             Character = 'a'
         }, // a -> 0;
         new HuffmanNode
         {
             Frequency = 5,
             Left      = new HuffmanNode
             {
                 Character = 'b',
                 Frequency = 3,
             },
             Right = new HuffmanNode
             {
                 Character = 'c',
                 Frequency = 2,
             }
         }, // b -> 0; c -> 1
         new HuffmanNode
         {
             Frequency = 11,
             Left      = new HuffmanNode
             {
                 Character = 'a',
                 Frequency = 5,
             },
             Right = new HuffmanNode
             {
                 Frequency = 6,
                 Left      = new HuffmanNode
                 {
                     Character = 'c',
                     Frequency = 2,
                 },
                 Right = new HuffmanNode
                 {
                     Character = 'b',
                     Frequency = 4,
                 }
             }
         }, // a -> 0; b -> 11; c -> 10;
         new HuffmanNode
         {
             Frequency = 12,
             Left      = new HuffmanNode
             {
                 Character = 'a',
                 Frequency = 5,
             },
             Right = new HuffmanNode
             {
                 Character = 'b',
                 Frequency = 7,
             },
         }, // a -> 0; b -> 1
         new HuffmanNode
         {
             Frequency = 12,
             Left      = new HuffmanNode
             {
                 Character = 'b',
                 Frequency = 7,
             },
             Right = new HuffmanNode
             {
                 Character = 'a',
                 Frequency = 5,
             },
         } // a -> 1; b -> 0
     };
     return(_trees);
 }
 public HuffmanDecompressTestCase(double timeLimit, Exception expectedException, string description, HuffmanNode tree, BitArray encoding, string expectedResult)
     : base(timeLimit, expectedException, description)
 {
     this.tree           = tree;
     this.encoding       = encoding;
     this.expectedResult = expectedResult;
     treeCopy            = HuffmanNode_DeepClone(tree);
 }
 public static HuffmanNode HuffmanNode_DeepClone(HuffmanNode node)
 {
     return(node == null
         ? null
         : HuffmanNode_Create(node));
 }
 public bool Put(HuffmanNode node) => queue.Put(node, node.Frequency); // Dodaje węzeł Huffmana do kolejki