private static HuffmanElement_t[] CreateHuffmanTable(byte[] data)
        {
            List <Data_t> character = new List <Data_t>();

            for (UInt64 i = 0; i < (UInt64)data.LongLength; ++i) // Wrazie bardzo długich plików wykorzystuje unsigned long
            {
                bool isExist = false;
                for (int j = 0; j < character.Count; ++j)
                {
                    if (data[i] == character[j].symbol)
                    {
                        isExist = true;                // Element już wystąpił wcześniej

                        Data_t element = character[j]; // Zwiększam liczbe wystąpień
                        element.probability++;
                        character[j] = element;
                    }
                }
                if (isExist == false) // Element wcześniej nie występował
                {
                    character.Add(new Data_t(data[i]));
                }
            }

            HuffmanTree hTree = new HuffmanTree(character);

            HuffmanElement_t[] hTab = hTree.GetHuffmanTable();

            return(hTab);
        }
        public HuffmanTree(List <Data_t> data)                         // Stworzenie drzewa Huffmana
        {
            List <Tree <Data_t> > nTree = new List <Tree <Data_t> >(); // Stworzenie drzew binarnych, gdzie węzły przechowują symbol i prawdopodobieństwo

            foreach (Data_t n in data)
            {
                nTree.Add(new Tree <Data_t>(n));
            }

            if (nTree.Count == 1) // Jeżeli data składa się tylko z jednego znaku
            {
                Tree <Data_t> leaf = nTree.First();
                nTree.RemoveAt(0);

                Data_t leafData = leaf.GetData();
                leafData.site = true;
                leaf.SetData(leafData);

                Data_t        newData = new Data_t(1u);
                Tree <Data_t> newTree = new Tree <Data_t>(newData);
                newTree.AddChild(leaf);

                tree = newTree;
            }
            else
            {
                nTree.Sort((first, second) => first.GetData().probability.CompareTo(second.GetData().probability)); // Sortowanie drzew po prawdopodobieństwie
                // Dopóki na liście jest więcej niż jedno drzewo usuwaj dwa drzewa z najmniejszym prawdopodobieństwem i twórz z nich jedno większe drzewo
                while (nTree.Count > 1)
                {
                    Tree <Data_t> left = nTree.First();  // Pierwsze drzewo na liście
                    nTree.RemoveAt(0);
                    Tree <Data_t> right = nTree.First(); // Drugie drzewo na liście przed usunięciem pierwszego
                    nTree.RemoveAt(0);


                    Data_t rightData = right.GetData();
                    rightData.site = true; // Zmiana strony
                    right.SetData(rightData);

                    Data_t        newData = new Data_t(left.GetData().probability + right.GetData().probability);
                    Tree <Data_t> newTree = new Tree <Data_t>(newData);
                    newTree.AddChild(left);
                    newTree.AddChild(right);

                    bool isAdded = false;
                    for (int i = 0; i < nTree.Count; ++i)
                    {
                        if (nTree[i].GetData().probability >= newTree.GetData().probability)
                        {
                            nTree.Insert(i, newTree);
                            isAdded = true;
                            break;
                        }
                    }
                    if (!isAdded)
                    {
                        nTree.Add(newTree);
                    }
                }
                tree = nTree.First();
            }
        }