예제 #1
0
        public HuffmanCode(T[] startingData)
        {
            HuffmanList <T> list = GenerateStartingList(startingData);

            tree = GenerateTree(list);
            //tree.PrintTree();
        }
예제 #2
0
        private HuffmanList <T> GenerateStartingList(T[] data)
        {
            Dictionary <T, int> dataCount = CalculateDataCount(data);

            HuffmanList <T> list = new HuffmanList <T>();

            foreach (KeyValuePair <T, int> pair in dataCount)
            {
                list.Add(pair.Key, (double)pair.Value / (double)data.Length);
            }
            return(list);
        }
예제 #3
0
        private HuffmanTree <T> GenerateTree(HuffmanList <T> list)
        {
            IHuffmanNode[]      curNodes = new IHuffmanNode[4];
            HuffmanListNode <T> listFirst, listSecond;
            HuffmanListNode <HuffmanTree <T> > treeFirst, treeSecond;
            HuffmanList <HuffmanTree <T> >     subTrees = new HuffmanList <HuffmanTree <T> >();

            while (list.Count > 0 || subTrees.Count > 1)
            {
                list.GetTwoLowestFreqNodes(out listFirst, out listSecond);
                subTrees.GetTwoLowestFreqNodes(out treeFirst, out treeSecond);
                curNodes[0] = listFirst;
                curNodes[1] = listSecond;
                if (treeFirst != null)
                {
                    curNodes[2] = treeFirst.info.root;
                    if (treeSecond != null)
                    {
                        curNodes[3] = treeSecond.info.root;
                    }
                    else
                    {
                        curNodes[3] = null;
                    }
                }
                else
                {
                    curNodes[2] = curNodes[3] = null;
                }


                double lowestFreq = double.MaxValue, secondLowestFreq = double.MaxValue;
                int    lowestIndex = 0, secondLowestIndex = 1;

                for (int i = 0; i < 4; ++i)
                {
                    if (curNodes[i] != null)
                    {
                        if (curNodes[i].GetFrequency() <= lowestFreq)
                        {
                            secondLowestFreq  = lowestFreq;
                            secondLowestIndex = lowestIndex;
                            lowestFreq        = curNodes[i].GetFrequency();
                            lowestIndex       = i;
                        }
                        else if (curNodes[i].GetFrequency() <= secondLowestFreq)
                        {
                            secondLowestFreq  = curNodes[i].GetFrequency();
                            secondLowestIndex = i;
                        }
                    }
                }
                //If both nodes are from list, create a new subtree
                if (lowestIndex < 2 && secondLowestIndex < 2)
                {
                    HuffmanLeafNode <T> first      = new HuffmanLeafNode <T>(listFirst.info, listFirst.frequency);
                    HuffmanLeafNode <T> second     = new HuffmanLeafNode <T>(listSecond.info, listSecond.frequency);
                    HuffmanTree <T>     newSubTree = new HuffmanTree <T>(first, second);
                    subTrees.Add(newSubTree, newSubTree.GetRootFrequency());
                    list.RemoveNode(listFirst);
                    list.RemoveNode(listSecond);
                }
                else if (lowestIndex >= 2 && secondLowestIndex >= 2)   //Merge trees
                {
                    treeFirst.info.Combine(treeSecond.info.root);
                    subTrees.SetFrequency(treeFirst, treeFirst.info.GetRootFrequency());
                    subTrees.RemoveNode(treeSecond);
                }
                else
                {
                    HuffmanLeafNode <T> first = new HuffmanLeafNode <T>(listFirst.info, listFirst.frequency);
                    treeFirst.info.Combine(first);
                    subTrees.SetFrequency(treeFirst, treeFirst.info.GetRootFrequency());
                    list.RemoveNode(listFirst);
                }
            }
            return(subTrees[0].info);
        }