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(); } }