Kod Huffmana - wytłumaczenie części wstawiania elementu do listy

0

Witam
Prosiłbym o wytłumaczenie tej procedury a konkretnie wstawiania elementu w odpowiednie miejsce na liście.

 begin
     while true do begin
           e:=root;                  //Bierzemy pierwsze dwa elementy (najmniejsze)
           e1:=e^.next;

           if e1=nil then break;     //Jeśli na liście jest tylko jeden element, kończymy

           root:=e1^.next;           //Usuwawmy te elementy z listy

           new(n);                       //Tworzymy nowy węzeł
           n^.left:=e;                   //Dołączamy do niego poprzednie elementy
           n^.right:=e1;
           n^.count:=e^.count+e1^.count; //Sumujemy ilości wystąpień

           //Wstawiamy węzeł w odpowiednim miejscu

           if (root = nil) or (n^.count <= root^.count) then begin
              n^.next := root;
              root := n;
              continue;
           end;

           r := root;

           while (r^.next <> nil) and (n^.count > r^.next^.count) do r := r^.next;

           n^.next := r^.next;
           r^.next := n;


     end;
end;
0

To jet kod do budowania drzewa Huffmana. Na początku zapewne masz las jednoelementowych drzew ułożonych w listę posortowaną po wadze (tutaj: count), od najmniejszej do największej. Procedura budowania drzewa Huffmana wygląda tak, że dopóki jest więcej niż jedno drzewo w lesie to łączysz dwa najlżejsze drzewa w jedno drzewo, którego waga jest równa sumie wag drzew z których jest zbudowana (czyli, przez indukcję, sumie wag liści).

"Odpowiednie miejsce na liście" to takie miejsce, by po wstawieniu lista była dalej posortowana względem wag drzew.

Po zbudowaniu drzewa Huffmana możesz obliczyć długości kodów Huffmana dla każdego liścia - jest ona po prostu równa głębokości liścia w drzewie. Sam kod możesz wygenerować przeglądając drzewo ('zwykły' Huffman), albo możesz posortować symbole z liści względem długości ich kodów i nadawać kolejne kody bitowe (wtedy dostaniesz 'canonical Huffman').

0

Dobrze dzięki za wytłumaczenie ale ja już to wiedziałem, chodzi mi konkretnie o linijki które odpowiadają za wstawianie nowego węzła w odpowiednie miejsce listy.

Pozdrawiam

0

Masz napisane przecież. Można nieco bardziej sprecyzować:

           //Wstawiamy węzeł w odpowiednim miejscu

           // jeśli lista pusta (po wyciągnięciu) lub waga nie większa niż nowy element początkowy to
           // użyj specjalnego wstawiania na początek i przejdź do następnej iteracji
           if (root = nil) or (n^.count <= root^.count) then begin
              n^.next := root;
              root := n;
              continue;
           end;

           // w innym wypadku przejdź do miejsca na liście tuż po ostatnim węźle lżejszym niż wstawiany
           r := root;

           while (r^.next <> nil) and (n^.count > r^.next^.count) do r := r^.next;

           // i wstaw go przepinając wskaźniki
           n^.next := r^.next;
           r^.next := n;

1 użytkowników online, w tym zalogowanych: 0, gości: 1