Kody Huffmana¶
Opis problemu¶
Implementacja¶
Opis implementacji¶
Klasa Node reprezentuje węzeł w drzewie Huffmana. Każdy węzeł przechowuje literę (letter), wartość (value), lewe poddrzewo (left) i prawe poddrzewo (right).
Funkcja create_tree tworzy drzewo Huffmana na podstawie podanego tekstu. Na początku tworzona jest pusta lista nodes_list, która będzie przechowywać węzły drzewa. Następnie tworzony jest zbiór unikalnych liter z tekstu. Dla każdej litery w zbiorze, tworzony jest węzeł i dodawany do listy nodes_list, gdzie wartość węzła to liczba wystąpień danej litery w tekście. Węzły są sortowane rosnąco względem wartości. Następnie, w pętli, dopóki lista nodes_list ma więcej niż jeden element, usuwane są dwa pierwsze węzły z najmniejszymi wartościami, a następnie tworzony jest nowy węzeł, który jest sumą wartości tych dwóch węzłów. Nowy węzeł jest dodawany do listy nodes_list i lista jest sortowana ponownie. Proces ten jest powtarzany, aż do momentu, gdy w liście nodes_list pozostaje tylko jeden węzeł, który jest korzeniem drzewa. Ten korzeń jest zwracany przez funkcję create_tree.
Funkcja create_codes tworzy kodowanie dla każdej litery na podstawie drzewa Huffmana. Funkcja jest rekurencyjna. Jeśli dany węzeł nie ma dzieci (lewej i prawej gałęzi), oznacza to, że reprezentuje on konkretną literę. W takim przypadku przypisywany jest kod (ścieżka) do tej litery w słowniku codes. Jeśli dany węzeł ma lewego potomka, rekurencyjnie wywoływana jest funkcja create_codes dla lewego potomka, a do kodu (ścieżki) dodawane jest "0". Jeśli dany węzeł ma prawego potomka, rekurencyjnie wywoływana jest funkcja create_codes dla prawego potomka, a do kodu (ścieżki) dodawane jest "1".
Funkcja compress kompresuje tekst na podstawie utworzonych kodów dla liter. Przechodząc przez każdą literę w tekście, kod dla danej litery jest dodawany do zmiennej compressed.
Funkcja decompress przyjmuje skompresowany tekst (compressed) oraz korzeń drzewa Huffmana (tree). Iteruje po każdym bicie w skompresowanym tekście. Jeśli bit jest równy "0", przechodzi do lewego potomka węzła bieżącego (current_node), a jeśli bit jest równy "1", przechodzi do prawego potomka. Gdy osiągnie liść drzewa (czyli węzeł, który nie ma dzieci), dodaje jego literę do dekompresowanego tekstu (decompressed) i przechodzi z powrotem do korzenia drzewa. Proces ten powtarza się, aż do przetworzenia wszystkich bitów skompresowanego tekstu.
W przykładzie, tekst "papuga" jest kompresowany. Na początku tworzone jest drzewo Huffmana za pomocą funkcji create_tree. Następnie za pomocą funkcji create_codes tworzone są kody dla liter, które są przechowywane w słowniku codes. Następnie tekst jest kompresowany funkcją compress i wynikowy skompresowany tekst jest wyświetlany. Na końcu skompresowany tekst jest dekompresowany funkcją decompress i wynikowy zdekompresowany tekst jest wyświetlany.