Example #1
0
        private static List<bool> Traverse(Node node, char symbol, List<bool> data)
        {
            if (node.Left == null &&
                node.Right == null)
            {
                return symbol == node.Symbol ? data : null;
            }

            if (node.Left != null)
            {
                var path = new List<bool>();
                path.AddRange(data);
                path.Add(false);

                var left = Traverse(node.Left, symbol, path);
                if (left != null)
                {
                    return left;
                }
            }

            if (node.Right != null)
            {
                var path = new List<bool>();
                path.AddRange(data);
                path.Add(true);

                var right = Traverse(node.Right, symbol, path);
                if (right != null)
                {
                    return right;
                }
            }

            return null;
        }
Example #2
0
        public void Build(string text)
        {
            if (text == null)
            {
                throw new ArgumentNullException("text");
            }

            this._Root = null;
            var frequencies = new Dictionary<char, int>();
            this._Codes.Clear();

            foreach (var t in text)
            {
                int frequency;
                if (frequencies.TryGetValue(t, out frequency) == false)
                {
                    frequency = 0;
                }
                frequencies[t] = frequency + 1;
            }

            var nodes = frequencies.Select(
                symbol => new Node()
                {
                    Symbol = symbol.Key,
                    Frequency = symbol.Value,
                }).ToList();

            while (nodes.Count > 1)
            {
                var orderedNodes = nodes
                    .OrderBy(n => n.Frequency).ToList();

                if (orderedNodes.Count >= 2)
                {
                    var taken = orderedNodes.Take(2).ToArray();
                    var first = taken[0];
                    var second = taken[1];

                    var parent = new Node()
                    {
                        Symbol = '\0',
                        Frequency = first.Frequency + second.Frequency,
                        Left = first,
                        Right = second,
                    };

                    nodes.Remove(first);
                    nodes.Remove(second);
                    nodes.Add(parent);
                }

                this._Root = nodes.FirstOrDefault();
            }

            foreach (var frequency in frequencies)
            {
                var bits = Traverse(this._Root, frequency.Key, new List<bool>());
                if (bits == null)
                {
                    throw new InvalidOperationException(string.Format(
                        "could not traverse '{0}'", frequency.Key));
                }
                this._Codes.Add(frequency.Key, new BitArray(bits.ToArray()));
            }

            this.TotalBits = GetTotalBits(this._Root);
        }
Example #3
0
        private static int GetTotalBits(Node root)
        {
            var queue = new Queue<Node>();
            queue.Enqueue(root);

            int totalBits = 0;
            while (queue.Count > 0)
            {
                var node = queue.Dequeue();
                if (node.Left == null && node.Right == null)
                {
                    continue;
                }

                totalBits += node.Frequency;

                if (node.Left != null &&
                    node.Left.Left != null &&
                    node.Left.Right != null)
                {
                    queue.Enqueue(node.Left);
                }

                if (node.Right != null &&
                    node.Right.Left != null &&
                    node.Right.Right != null)
                {
                    queue.Enqueue(node.Right);
                }
            }

            return totalBits;
        }