Ejemplo n.º 1
0
 void PopulateSymbolTable(int[] frequencies)
 {
     Symbols = new HuffmanTableEntry[NumSymbols];
     for (int i = 0; i < NumSymbols; i++)
     {
         Symbols[i] = new HuffmanTableEntry {
             Symbol = i, Count = frequencies[i]
         };
     }
 }
Ejemplo n.º 2
0
        // TODO: This completely fails if there is only 1 observed symbol. We should fix this.
        // However, in practice there should always be at least one literal symbol + EOF symbol (shouldn't be compressing 0 byte files).
        public void ConstructTree()
        {
            var symbolsToProcess = new List <HuffmanTableEntry>(Symbols.Where(s => s.Count > 0));

            while (symbolsToProcess.Count > 1)
            {
                // Pop the lowest count symbols off the list, and insert a tree node each time you loop.
                // Loop until you only have one symbol, the top of the tree.
                var lowest1 = symbolsToProcess[0];
                var lowest2 = symbolsToProcess[1];
                if (lowest1.Count > lowest2.Count)
                {
                    lowest1 = symbolsToProcess[1];
                    lowest2 = symbolsToProcess[0];
                }

                for (int i = 2; i < symbolsToProcess.Count; i++)
                {
                    if (symbolsToProcess[i].Count < lowest1.Count)
                    {
                        lowest2 = lowest1;
                        lowest1 = symbolsToProcess[i];
                    }
                    else if (symbolsToProcess[i].Count < lowest2.Count)
                    {
                        lowest2 = symbolsToProcess[i];
                    }
                }
                // Now, lowest1 and lowest2 should point to the lowest two probability items in the list.
                // So, create a merged node with lowest two probability items.
                var merged = new HuffmanTableEntry {
                    Symbol = -1,
                    Count  = lowest1.Count + lowest2.Count
                };
                lowest1.Parent = merged;
                lowest2.Parent = merged;

                // Insert merged node and pop off lowest
                symbolsToProcess.Remove(lowest1);
                symbolsToProcess.Remove(lowest2);
                symbolsToProcess.Add(merged);
            }
        }