private void Process(string str)
 {
     _huffman = new Huffman();
     _tree    = (_huffman.Process(str));
     //_tree.PreOrder((x)=>CreateElement(x));
     RebuildTree();
 }
Beispiel #2
0
        /// <summary>
        /// 添加子节点
        /// </summary>
        /// <param name="huffmanNode"></param>
        /// <param name="parentNode"></param>
        void FillTreeNodes(HuffmanTreeNode huffmanNode, TreeNode parentNode)
        {
            TreeNode treeNode = new TreeNode(huffmanNode.Weight.ToString());

            //如果权重值包括在权重列表中,则树节点文本显示为红色
            if (weights.Contains(huffmanNode.Weight))
            {
                treeNode.ForeColor = Color.Red;
            }

            parentNode.Nodes.Add(treeNode);


            if (huffmanNode.LeftChild != -1)
            {
                HuffmanTreeNode left = huffmanTree[huffmanNode.LeftChild];

                FillTreeNodes(left, treeNode);
            }

            if (huffmanNode.RightChild != -1)
            {
                HuffmanTreeNode currentNode = huffmanTree[huffmanNode.RightChild];

                FillTreeNodes(currentNode, treeNode);
            }
        }
Beispiel #3
0
        private void WriteHuffmanTree(BitWriter bw, HuffmanTreeNode rootNode, int huffmanMode)
        {
            int bitDepth;

            switch (huffmanMode)
            {
            case 1:
                bitDepth = 4;
                break;

            case 2:
                bitDepth = 8;
                break;

            default:
                return;
            }

            var depthList = rootNode.Children;

            for (var i = 0; i < 16; i++)
            {
                var valuesWithBitCount = depthList.Count(x => x.IsLeaf);
                bw.WriteByte(valuesWithBitCount);

                foreach (var value in depthList.Where(x => x.IsLeaf).Select(x => x.Code))
                {
                    bw.WriteBits(value, bitDepth);
                }
                depthList = depthList.Where(x => !x.IsLeaf).SelectMany(x => x.Children).ToArray();
            }
        }
Beispiel #4
0
        private void SortHuffmanTree(HuffmanTreeNode rootNode)
        {
            var treeDepth = rootNode.GetDepth();

            IList <HuffmanTreeNode> previousDepthList = new List <HuffmanTreeNode> {
                rootNode
            };
            IList <HuffmanTreeNode> depthList = rootNode.Children;

            for (int i = 0; i < treeDepth; i++)
            {
                if (depthList.All(x => !x.IsLeaf))
                {
                    previousDepthList = depthList;
                    depthList         = previousDepthList.SelectMany(x => x.Children).ToList();
                    continue;
                }

                var ordered = depthList.OrderBy(x => !x.IsLeaf).ToList();
                for (var j = 0; j < ordered.Count; j++)
                {
                    previousDepthList[j / 2].Frequency      -= previousDepthList[j / 2].Children[j % 2].Frequency;
                    previousDepthList[j / 2].Children[j % 2] = ordered[j];
                    previousDepthList[j / 2].Frequency      += ordered[j].Frequency;
                }

                previousDepthList = ordered.Where(x => !x.IsLeaf).ToList();
                depthList         = previousDepthList.SelectMany(x => x.Children).ToList();
            }
        }
Beispiel #5
0
        private List <HuffmanTreeNode> LabelTreeNodes(HuffmanTreeNode rootNode)
        {
            var labelList   = new List <HuffmanTreeNode>();
            var frequencies = new List <HuffmanTreeNode> {
                rootNode
            };

            while (frequencies.Any())
            {
                // Assign a score to each frequency node in the root
                var scores = frequencies.Select((freq, i) => new { Node = freq, Score = freq.Code - i });

                // Get node with lowest score
                var node = scores.OrderBy(freq => freq.Score).First().Node;

                // Remove that node from the tree root
                frequencies.Remove(node);

                node.Code = labelList.Count - node.Code;
                labelList.Add(node);

                // Loop through all children that aren't leaves
                foreach (var child in node.Children.Reverse().Where(child => !child.IsLeaf))
                {
                    child.Code = labelList.Count;
                    frequencies.Add(child);
                }
            }

            return(labelList);
        }
Beispiel #6
0
        public HuffmanTreeNode Build(List <HuffmanTreeNode> t)
        {
            var tree = new HuffmanTree();
            var len  = t.Count;

            // создание дерева
            while (t.Count != 1) // пока в дереве более одного элемента
            {
                ListSort(t);     // сортировка элементов по возрастанию

                // создание левого поддерева
                var l = t[0];
                // удаление
                t.RemoveAt(0);
                // создание правого поддерева
                var r = t[0];
                //удаление
                t.RemoveAt(0);

                // создание нового элемента с правым и левым поддеревом
                HuffmanTreeNode parent = new HuffmanTreeNode(l, r);
                parent.weight = l.weight + r.weight; // вес родителя
                t.Add(parent);
                Print(t);
            }

            // последний оставшийся в списке - корень дерева
            HuffmanTreeNode root = t[0];

            root.Length = len;
            return(root);
        }
Beispiel #7
0
        private HuffmanTreeNode CreateAndSortTree(List <HuffmanTreeNode> frequencies)
        {
            //Sort and create the tree
            while (frequencies.Count > 1)
            {
                // Order frequencies ascending
                frequencies = frequencies.OrderBy(n => n.Frequency).ToList();

                // Create new tree node with the 2 elements of least frequency
                var leastFrequencyNode = new HuffmanTreeNode
                {
                    Frequency = frequencies[0].Frequency + frequencies[1].Frequency,
                    Children  = frequencies.Take(2).ToArray()
                };

                // Remove those least frequency elements and append new tree node to frequencies
                frequencies = frequencies.Skip(2).Concat(new[] { leastFrequencyNode }).ToList();

                // This ultimately results in a tree like structure where the most frequent elements are closer to the root;
                // while less frequent elements are farther from it

                // Example:
                // (F:4)
                //   (F:3)
                //     (F:1)
                //     (F:2)
                //   (F:1)
            }

            return(frequencies.First());
        }
Beispiel #8
0
 public HuffmanDecoder(HuffmanTree huffmanTree)
 {
     if (huffmanTree == null)
     {
         throw new ArgumentNullException(nameof(huffmanTree));
     }
     m_node = huffmanTree.Root;
 }
Beispiel #9
0
 public HuffmanTreeNode(HuffmanTreeNode left, HuffmanTreeNode right)
 {
     Left = left;
     Right = right;
     Left.Parent = Right.Parent = this;
     if (ByteCount == null)
         ByteCount = new ByteCount();
     this.ByteCount.Count = Left.ByteCount.Count + Right.ByteCount.Count;
 }
Beispiel #10
0
        public void IsLeaf_trueWhenOnlyNode()
        {
            //given
            //when
            var node = new HuffmanTreeNode <char>(value: 'a', quantity: 3);

            //then
            Assert.IsTrue(node.IsLeaf);
        }
Beispiel #11
0
        public void IsLeaf_TrueWhenHasParent()
        {
            //given
            //when
            var node = new HuffmanTreeNode <char>(value: 'a', quantity: 3);

            node.Parent = new HuffmanTreeNode <char>(value: 'b', quantity: 4);
            //then
            Assert.IsTrue(node.IsLeaf);
        }
Beispiel #12
0
        public void IsLeaf_FalseWhenHasLeftChild()
        {
            //given
            //when
            var node = new HuffmanTreeNode <char>(value: 'a', quantity: 3);

            node.LeftChild = new HuffmanTreeNode <char>(value: 'b', quantity: 4);
            //then
            Assert.IsFalse(node.IsLeaf);
        }
Beispiel #13
0
 public HuffmanTreeNode(HuffmanTreeNode left, HuffmanTreeNode right)
 {
     Left        = left;
     Right       = right;
     Left.Parent = Right.Parent = this;
     if (ByteCount == null)
     {
         ByteCount = new ByteCount();
     }
     this.ByteCount.Count = Left.ByteCount.Count + Right.ByteCount.Count;
 }
Beispiel #14
0
        private static byte Decode(BitArray bits, ref int bitIndex, HuffmanTreeNode root)
        {
            var p = root;

            while (!p.IsLeafNode)
            {
                var bit = bits[bitIndex++];
                p = p.Children[bit ? 1 : 0];
            }
            return((byte)p.Item);
        }
        public void GetDecoder_ReturnsOneSymbolDecoder_WhenOneSymbolOnly()
        {
            //given
            var builder  = new HuffmanCodecBuilder <char>();
            var treeRoot = new HuffmanTreeNode <char>(value: 'a', quantity: 1);
            //when
            var decoder = builder.GetDecoder(treeRoot);

            //then
            Assert.IsInstanceOfType(decoder, typeof(OneSymbolDecoder <char>));
        }
Beispiel #16
0
 private void CreateHuffmanTreeNodes(List <HuffmanTreeComponent> nodes)
 {
     if (nodes.Count > 1)
     {
         HuffmanTreeNode huffmanTreeNode = new HuffmanTreeNode(nodes[1], nodes[0]);
         nodes.RemoveAt(0);
         nodes.RemoveAt(0);
         nodes.Add(huffmanTreeNode);
         nodes.Sort();
         CreateHuffmanTreeNodes(nodes);
     }
 }
Beispiel #17
0
 /// <summary>
 /// Not returning anything. just add onto the dictionary as you go.
 /// </summary>
 /// <param name="root"></param>
 /// <param name="code"></param>
 /// <param name="table"></param>
 public void BuildTable(HuffmanTreeNode root, StringBuilder code, Dictionary <char, string> table)
 {
     if (root.leftChild != null)                              //Check if the node has children
     {
         BuildTable(root.LeftChild, code.Append('0'), table); //maybe create a temporary value for stringBuilder Code to combat globally udating "code" stringBuilder.
         BuildTable(root.RightChild, code.Append('1'), table);
     }
     else //We're at a character
     {
         table.Add(root.Data, code);
     }
 }
Beispiel #18
0
        static HuffmanTreeNode DoBuild(TreeNodeTraits nodeTraits)
        {
            if (nodeTraits == null)
            {
                return(null);
            }

            HuffmanTreeNode l = DoBuild(nodeTraits.Left);
            HuffmanTreeNode r = DoBuild(nodeTraits.Right);

            return(new HuffmanTreeNode(nodeTraits.Symbol, l, r));
        }
Beispiel #19
0
        private IValueWriter CreateValueWriter(int huffmanMode, HuffmanTreeNode rootNode)
        {
            switch (huffmanMode)
            {
            case 1:
            case 2:
                return(new HuffmanWriter(rootNode));

            default:
                return(new DefaultValueWriter());
            }
        }
Beispiel #20
0
        private void WriteTreeNode(BitWriter bw, HuffmanTreeNode huffmanTreeNode, int bitCount)
        {
            if (huffmanTreeNode.IsLeaf)
            {
                bw.WriteBit(0);
                bw.WriteBits(huffmanTreeNode.Code, bitCount);
                return;
            }

            bw.WriteBit(1);
            WriteTreeNode(bw, huffmanTreeNode.Children[0], bitCount);
            WriteTreeNode(bw, huffmanTreeNode.Children[1], bitCount);
        }
Beispiel #21
0
        public void Push(bool bit)
        {
            if (m_node == null)
            {
                throw new InvalidOperationException("Cannot walk an empty tree.");
            }
            if (m_node.IsLeaf)
            {
                throw new InvalidOperationException("Cannot walk further from a leaf.");
            }

            m_node = bit ? m_node.RightChild : m_node.LeftChild;
        }
Beispiel #22
0
        private static List <bool> GetCode(HuffmanTreeNode leafNode)
        {
            Debug.Assert(leafNode.IsLeafNode);
            var p    = leafNode;
            var bits = new List <bool>();

            while (p.Parent != null)
            {
                bits.Add(p.Parent.LeftChild != p);
                p = p.Parent;
            }
            bits.Reverse();
            return(bits);
        }
        public void Compare_ComparesBySubTreeLengthSecond()
        {
            //given
            var a           = new HuffmanTreeNode <char>('a', 10, 1);
            var b           = new HuffmanTreeNode <char>('b', 10, 2);
            var c           = new HuffmanTreeNode <char>('c', 10, 0);
            var orderedList = new List <HuffmanTreeNode <char> >()
            {
                c, a, b
            };

            //then
            AssertOrderCompareByPairs(orderedList);
        }
        public void Compare_ComparesByCustomCompareLast()
        {
            //given
            var a           = new HuffmanTreeNode <char>('a', 10, 0);
            var b           = new HuffmanTreeNode <char>('b', 10, 0);
            var c           = new HuffmanTreeNode <char>('c', 10, 0);
            var orderedList = new List <HuffmanTreeNode <char> >()
            {
                a, b, c
            };

            //then
            AssertOrderCompareByPairs(orderedList);
        }
        public void Compare_ComparesByQuantitiyFirst()
        {
            //given
            var a           = new HuffmanTreeNode <char>('a', 10, 1);
            var b           = new HuffmanTreeNode <char>('b', 4, 2);
            var c           = new HuffmanTreeNode <char>('c', 15, 0);
            var orderedList = new List <HuffmanTreeNode <char> >()
            {
                b, a, c
            };

            //then
            AssertOrderCompareByPairs(orderedList);
        }
        /// <summary>
        ///     以指定权重字典构造哈夫曼树
        /// </summary>
        /// <param name="weightDict">指定权重字典</param>
        /// <param name="keyComparer">键比较器</param>
        /// <returns></returns>
        public static HuffmanTree <T> CreateFromWeightDictionary(Dictionary <T, ulong> weightDict  = null,
                                                                 IEqualityComparer <T> keyComparer = null)
        {
            // 如果权重字典为空,则直接返回一个空树
            if (weightDict == null || weightDict.Count == 0)
            {
                return(new HuffmanTree <T>(keyComparer));
            }
            // 使用权重字典的数据构造一系列哈夫曼叶子结点
            var huffmanNodes = weightDict.Select(kps =>
                                                 new HuffmanTreeNode(new HuffmanTreeLeafNodeData <T>(kps.Key, kps.Value))).ToList();
            // 使用自定义可重复键的键比较器来建立空的 SortedList 对象
            var sortedList =
                new SortedList <ulong, HuffmanTreeNode>(new DuplicateKeyComparser <ulong>());

            // 遍历可迭代的哈夫曼叶子结点向 SortedList 对象中添加键值对
            foreach (var node in huffmanNodes)
            {
                sortedList.Add(node.Data.Weight, node);
            }
            // 循环直到 SortedList 对象中对象不足两个
            while (sortedList.Count >= 2)
            {
                // 依次从 SortedList 对象中弹出两个权重最小的结点
                var minNode1 = sortedList.ElementAt(0);
                sortedList.RemoveAt(0);
                var minNode2 = sortedList.ElementAt(0);
                sortedList.RemoveAt(0);
                // 将弹出的两个结点按照哈夫曼结点相加规则合并为一个哈夫曼结点
                var newNode = minNode1.Value + minNode2.Value;
                // 将合并好的新结点重新加回 SortedList 对象中
                sortedList.Add(newNode.Data.Weight, newNode);
            }

            var onlyOneNode = sortedList.First().Value;

            // 不幸的是,有可能只有一个叶子结点,这是相当特殊的情况,这个时候需要手动构造一个根结点
            // ReSharper disable once InvertIf
            if (huffmanNodes.Count() == 1)
            {
                onlyOneNode.Data.Code = false;
                onlyOneNode           = new HuffmanTreeNode(onlyOneNode, null);
            }

            // 存在权重字典为空的情况,在这种情况下构造的 SortedListed 对象内键值对数量会为 0 。此时应返回空树
            return(sortedList.Count == 0
                ? new HuffmanTree <T>(keyComparer)
                : new HuffmanTree <T>(onlyOneNode, keyComparer));
        }
Beispiel #27
0
 public HuffmanTree(HuffmanLeafNode <T> firstInit, HuffmanLeafNode <T> secondInit)
 {
     root = new HuffmanTreeNode();
     if (firstInit.frequency > secondInit.frequency)
     {
         root.left  = secondInit;
         root.right = firstInit;
     }
     else
     {
         root.left  = firstInit;
         root.right = secondInit;
     }
     CalcRootFrequency();
 }
Beispiel #28
0
        /// <summary>
        /// If string a.Length is less than string b.Length , then return true.
        /// </summary>
        /// <param name="tree"></param>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public bool CheckLengths(HuffmanTreeNode tree, string a, string b) //
        {
            Dictionary <char, string> table = new Dictionary <char, string>();

            BuildTable(tree, new StringBuilder(), table);

            if (GetEncoding(table, a).Length < GetEncoding(table, b).Length)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
        private void RebuildTree()
        {
            /*
             * Принцип роботи оснований на особливості бінарного дерева пошуку:
             * воно не може мати одинакових елементів
             * Отже потрібно створити словник який матиме в ключах значення дерева а в значеннях - об'екти
             */
            RemoveAllLines(); //Видаляємо всі лінії
            foreach (var item in _treeElements)
            {
                item.Value.Destroy();
            }
            _garbage.Clear();
            Console.WriteLine("==========");
            var t = 0;

            _tree.Draw((x, y, v, oldv) =>
            {
                //Якщо в словнику є елемент з таким значенням то використовуємо його якщо ж ні створюємо новий
                var current = CreateElement(v);
                //Запускаємо переміщення ноди в нову позицію
                current.Transform.TweenLocalPositionTo(new Vector2(x * 50, y * 50), 0.5f).Start();
                Entity elem = current, parent = null;



                if (oldv != null && _treeElements.FirstOrDefault(e => e.Key == oldv).Value != null)
                {
                    parent = _treeElements.FirstOrDefault(e => e.Key == oldv).Value;
                    var f  = _garbage.TryGetValue(parent.Name, out var res);

                    /*if (f)
                     *  Console.WriteLine($"{parent.Name} {res}");*/
                    if (_garbage.ContainsKey(parent.Name))
                    {
                        _garbage[parent.Name]++;
                    }
                    else
                    {
                        _garbage.Add(parent.Name, 1);
                    }
                }

                Core.StartCoroutine(DrawLine(elem, parent, t++));
            }, _tree.Length * 2); //Викликаємо відрисовку*/

            _tree = new HuffmanTreeNode();
        }
Beispiel #30
0
        private static Tuple <HuffmanTreeNode, HuffmanTreeNode[]> BuildTree(int[] freqArray)
        {
            var nodeArr = new HuffmanTreeNode[MaxLength];

            for (var i = 0; i < freqArray.Length; i++)
            {
                nodeArr[i] = new HuffmanTreeNode(i, freqArray[i], i);
            }
            var priQueue = new SortedSet <HuffmanTreeNode>(nodeArr);

            Debug.Assert(priQueue.Count == nodeArr.Length);
            var leafNodeArr = new HuffmanTreeNode[MaxLength];

            var leafIndex = 0;
            var id        = freqArray.Length;

            while (priQueue.Count >= 2)
            {
                var node1 = priQueue.Min();
                if (!priQueue.Remove(node1))
                {
                    Debug.Assert(false);
                }
                var node2 = priQueue.Min();
                if (!priQueue.Remove(node2))
                {
                    Debug.Assert(false);
                }
                if (node1.IsLeafNode)
                {
                    leafNodeArr[leafIndex++] = node1;
                }
                if (node2.IsLeafNode)
                {
                    leafNodeArr[leafIndex++] = node2;
                }
                if (!priQueue.Add(new HuffmanTreeNode(node1, node2, id++)))
                {
                    Debug.Assert(false);
                }
            }
#if DEBUG
            var list = priQueue.Min().Traverse().ToList();
            Debug.Assert(list.Count == 2 * MaxLength - 1);
            Debug.Assert(list.Count(item => item.IsLeafNode) == MaxLength);
#endif
            return(Tuple.Create(priQueue.Min(), leafNodeArr));
        }
        public void GetCoder_ReturnsHuffmanDecoder_WhenMoreThanOneSymbol()
        {
            //given when
            var builder    = new HuffmanCodecBuilder <char>();
            var treeRoot   = new HuffmanTreeNode <char>(value: 'a', quantity: 1);
            var leftChild  = new HuffmanTreeNode <char>(value: 'b', quantity: 1);
            var rightChild = new HuffmanTreeNode <char>(value: 'c', quantity: 1);

            treeRoot.LeftChild  = leftChild;
            treeRoot.RightChild = rightChild;
            leftChild.Parent    = rightChild.Parent = treeRoot;
            //when
            var decoder = builder.GetDecoder(treeRoot);

            //then
            Assert.IsInstanceOfType(decoder, typeof(HuffmanDecoder <char>));
        }