Jak skompresować dane za pomocą kodowania Huffmana: 10 kroków

Spisu treści:

Jak skompresować dane za pomocą kodowania Huffmana: 10 kroków
Jak skompresować dane za pomocą kodowania Huffmana: 10 kroków

Wideo: Jak skompresować dane za pomocą kodowania Huffmana: 10 kroków

Wideo: Jak skompresować dane za pomocą kodowania Huffmana: 10 kroków
Wideo: ReTo ft. Avi - BMW (prod. PSR) 2024, Kwiecień
Anonim

Algorytm Huffmana służy do kompresji lub kodowania danych. Normalnie każdy znak w pliku tekstowym jest przechowywany jako osiem bitów (cyfry, 0 lub 1), które są odwzorowywane na ten znak przy użyciu kodowania zwanego ASCII. Plik zakodowany w Huffmana rozbija sztywną 8-bitową strukturę tak, że najczęściej używane znaki są przechowywane w zaledwie kilku bitach ('a' może być "10" lub "1000" zamiast ASCII, czyli "01100001"). Najmniej popularne znaki często zajmują znacznie więcej niż 8 bitów ('z' może być "00100011010"), ale ponieważ występują tak rzadko, kodowanie Huffmana, ogólnie rzecz biorąc, tworzy znacznie mniejszy plik niż oryginał.

Kroki

Część 1 z 2: Kodowanie

Kompresuj dane za pomocą kodowania Huffmana Krok 1
Kompresuj dane za pomocą kodowania Huffmana Krok 1

Krok 1. Policz częstotliwość każdego znaku w pliku do zakodowania

Dołącz fikcyjny znak, aby oznaczyć koniec pliku - będzie to ważne później. Na razie nazwij go EOF (koniec pliku) i oznacz go jako mający częstotliwość 1.

Na przykład, jeśli chcesz zakodować plik tekstowy z napisem „ab ab cab”, miałbyś „a” z częstotliwością 3, „b” z częstotliwością 3, „” (spacja) z częstotliwością 2, „c” z częstotliwością 1, oraz EOF z częstotliwością 1

Kompresuj dane za pomocą kodowania Huffmana Krok 2
Kompresuj dane za pomocą kodowania Huffmana Krok 2

Krok 2. Przechowuj znaki jako węzły drzewa i umieść je w kolejce priorytetowej

Będziesz budować duże drzewo binarne z każdym znakiem jako liściem, więc powinieneś przechowywać znaki w takim formacie, aby mogły stać się węzłami drzewa. Umieść te węzły w kolejce priorytetowej z częstotliwością każdego znaku jako priorytetem węzła.

  • Drzewo binarne to format danych, w którym każda część danych jest węzłem, który może mieć maksymalnie jednego rodzica i dwoje dzieci. Często jest rysowany jako rozgałęzione drzewo, stąd nazwa.
  • Kolejka to zbiór danych o trafnej nazwie, w którym pierwsza rzecz, która trafia do kolejki, jest również pierwszą rzeczą, która wychodzi (jak czekanie w kolejce). W kolejce priorytetowej dane są przechowywane w kolejności ich priorytetów, tak aby pierwsza rzecz, która wyjdzie, to najpilniejsza rzecz, rzecz o najniższym priorytecie, a nie pierwsza rzecz w kolejce.
  • W przykładzie „ab ab cab” kolejka priorytetowa wyglądałaby tak: {'c':1, EOF:1, ' ':2, 'a':3, 'b':3}
Kompresuj dane za pomocą kodowania Huffmana Krok 3
Kompresuj dane za pomocą kodowania Huffmana Krok 3

Krok 3. Zacznij budować swoje drzewo

Usuń (lub usuń z kolejki) dwie najpilniejsze rzeczy z kolejki priorytetowej. Utwórz nowy węzeł drzewa, który będzie rodzicem tych dwóch węzłów, przechowując pierwszy węzeł jako jego lewy potomek, a drugi jako jego prawy potomek. Priorytet nowego węzła powinien być sumą priorytetów jego dziecka. Następnie umieść ten nowy węzeł w kolejce priorytetowej.

Kolejka priorytetowa wygląda teraz tak: {' ':2, nowy węzeł:2, 'a':3, 'b':3}

Kompresuj dane za pomocą kodowania Huffmana Krok 4
Kompresuj dane za pomocą kodowania Huffmana Krok 4

Krok 4. Zakończ budowę swojego drzewa:

powtarzaj powyższy krok, aż w kolejce będzie tylko jeden węzeł. Zauważ, że oprócz węzłów, które utworzyłeś dla znaków i ich częstotliwości, będziesz także dekolejkować, zamieniać w drzewa i ponownie umieszczać w kolejce węzły nadrzędne, węzły, które same są drzewami.

  • Kiedy skończysz, ostatni węzeł w kolejce będzie korzeniem drzewa kodowania, a wszystkie inne węzły będą od niego odchodzić.
  • Najczęściej używanymi znakami będą liście znajdujące się najbliżej wierzchołka drzewa, natomiast rzadko używane znaki będą umieszczone na dole drzewa, dalej od korzenia.
Kompresuj dane za pomocą kodowania Huffmana Krok 5
Kompresuj dane za pomocą kodowania Huffmana Krok 5

Krok 5. Utwórz mapę kodowania. Przejdź po drzewie, aby dotrzeć do każdej postaci. Za każdym razem, gdy odwiedzasz lewe dziecko węzła, jest to „0”. Za każdym razem, gdy odwiedzasz właściwe dziecko węzła, jest to „1”. Kiedy dotrzesz do postaci, zapisz ją z sekwencją zer i jedynek, które zajęło jej dotarcie. Ta sekwencja jest tym, co znak będzie zakodowany w skompresowanym pliku. Przechowuj postacie i ich sekwencje na mapie.

  • Na przykład zacznij od korzenia. Odwiedź lewe dziecko korzenia, a następnie odwiedź lewe dziecko tego węzła. Ponieważ węzeł, w którym się teraz znajdujesz, nie ma żadnych dzieci, osiągnąłeś postać. To jest ' '. Ponieważ dwukrotnie przeszedłeś w lewo, aby się tu dostać, kodowanie znaku „” to „00”.
  • Dla tego drzewa mapa będzie wyglądać tak: {' ':"00", 'a':"10", 'b':"11", 'c':"010", EOF:"011"}.
Kompresuj dane za pomocą kodowania Huffmana Krok 6
Kompresuj dane za pomocą kodowania Huffmana Krok 6

Krok 6. W pliku wyjściowym dołącz mapę kodowania jako nagłówek

Umożliwi to dekodowanie pliku.

Kompresuj dane za pomocą kodowania Huffmana Krok 7
Kompresuj dane za pomocą kodowania Huffmana Krok 7

Krok 7. Zakoduj plik

Dla każdego znaku w pliku, który ma zostać zakodowany, napisz sekwencję binarną, którą zachowałeś na mapie. Po zakończeniu kodowania pliku upewnij się, że dodałeś EOF na końcu.

  • W przypadku pliku „ab ab cab” zakodowany plik będzie wyglądał następująco: „1011001011000101011011”.
  • Pliki są przechowywane w bajtach (8 bitów lub 8 cyfr binarnych). Ponieważ algorytm kodowania Huffmana nie używa formatu 8-bitowego, zakodowane pliki często nie będą miały długości będącej wielokrotnością 8. Pozostałe cyfry zostaną wypełnione zerami. W takim przypadku na końcu pliku zostaną dodane dwa zera, co wygląda jak kolejna spacja. To może być problem: skąd dekoder wiedziałby, kiedy przestać czytać? Jednakże, ponieważ dodaliśmy znak końca pliku, dekoder przejdzie do tego, a następnie zatrzyma się, ignorując wszystko, co zostało dodane później.

Część 2 z 2: Dekodowanie

Kompresuj dane za pomocą kodowania Huffmana Krok 8
Kompresuj dane za pomocą kodowania Huffmana Krok 8

Krok 1. Przeczytaj plik zakodowany w formacie Huffmana

Najpierw przeczytaj nagłówek, który powinien być mapą kodowania. Użyj tego, aby zbudować drzewo dekodujące w ten sam sposób, w jaki zbudowałeś drzewo, którego użyłeś do zakodowania pliku. Dwa drzewa powinny być identyczne.

Kompresuj dane za pomocą kodowania Huffmana Krok 9
Kompresuj dane za pomocą kodowania Huffmana Krok 9

Krok 2. Wczytaj binarną jedną cyfrę na raz

Przechodź przez drzewo podczas czytania: jeśli czytasz jako „0”, przejdź do lewego dziecka węzła, w którym się znajdujesz, a jeśli czytasz jako „1”, przejdź do prawego dziecka. Kiedy dotrzesz do liścia (węzła bez dzieci), dotarłeś do postaci. Napisz znak do zdekodowanego pliku.

Ze względu na sposób, w jaki znaki są przechowywane w drzewie, kody dla każdego znaku mają właściwość prefiksu, dzięki czemu kodowanie binarne żadnego znaku nie może nigdy wystąpić na początku kodowania innego znaku. Kodowanie każdego znaku jest całkowicie unikalne. To znacznie ułatwia dekodowanie

Kompresuj dane za pomocą kodowania Huffmana Krok 10
Kompresuj dane za pomocą kodowania Huffmana Krok 10

Krok 3. Powtarzaj, aż dojdziesz do EOF

Gratulacje! Odkodowałeś plik.

Zalecana: