Пример #1
0
        /// <summary>
        /// Builds the prefix code tree.
        /// </summary>
        /// <returns>An optimal prefix code tree for given characters and their frequencies.</returns>
        private PrefixCodeTree BuildPrefixCodeTree()
        {
            // A MinPriorityQueue is used for selecting two nodes with minimal weights at a time
            MinPriorityQueue <PrefixCodeTree> pq = new MinPriorityQueue <PrefixCodeTree>(this.symbols.Length);

            // Add all leaf nodes to the priority queue separately
            for (int i = 0; i < this.symbols.Length; ++i)
            {
                PrefixCodeTree node = new PrefixCodeTree();
                node.Symbol = this.symbols[i];
                node.Weight = this.frequencies[i];
                pq.Enqueue(node);
            }

            // Select two nodes with minimal weights and join them under a new node until a root tree is built
            while (pq.Size > 1)
            {
                PrefixCodeTree first   = pq.Dequeue();
                PrefixCodeTree second  = pq.Dequeue();
                PrefixCodeTree newNode = new PrefixCodeTree();
                newNode.Symbol = null;
                newNode.Weight = first.Weight + second.Weight;
                newNode.Left   = first;
                newNode.Right  = second;
                pq.Enqueue(newNode);
            }

            // The last node in the queue is the root of the prefix code tree
            return(pq.Dequeue());
        }
Пример #2
0
 /// <summary>
 /// Traverses the code tree recursively and construct prefix codes at leaf nodes.
 /// </summary>
 /// <param name="tree">Prefix code tree.</param>
 /// <param name="path">Path to the current node from the tree root.</param>
 private void BuildCodes(PrefixCodeTree tree, string path)
 {
     if (tree.Symbol != null)
     {
         // This is a leaf node, a path has been found
         this.codes[tree.Symbol.Value] = path;
     }
     else
     {
         // Traverse left and right children with updated paths
         this.BuildCodes(tree.Left, path + "0");
         this.BuildCodes(tree.Right, path + "1");
     }
 }