Üniversite 3. sınıfta gördüğümüz derslerden biri olan Data Communications'da hocamızın verdiği bir projeydi Huffman Encode/Decode yapmayı sağlayan bir program yazmamız. Hocamız eğer Huffman Ağacını da ekrana çizdirirseniz bonus vereceğim demişti. Ben de çizdirme işlemini görsel kabiliyetleri çok yüksek olan Microsoft Windows Presentation Foundation'ı ( WPF ) kullandım. Peki Huffman Sıkıştırma Algoritmasını kısaca özetlemek gerekirse; girilen bir text input'unun içinde en çok geçen harfleri daha az bit ile kaydetme yöntemi. Daha ayrıntılı olarak aşağıda ekran görüntüleriyle anlatmaya çalışacağım.
Normal ( Sıkıştırılmamış ) bir text dosyasında 'a' veya 'e' harfinin diğer harfler ile aynı bit sayısında tutulurlar ve bunlar ASCII kodlamada 7-8 bit ile gösterilirler. Fakat 'a' ve 'e' harfine göre 'z' daha az kullanılıyor. Huffman Algoritmasına göre 'a' ve 'e' harfi daha az bit , 'z' 'nin ise daha fazla bit ile gösterilmesi bize büyük bir sıkıştırma sağlayacaktır.
Programda ilk önce girilen text'deki karakterlerin herbirinin sayısını buldum. Bütün harfleri bir düğüm olarak kabul ediyorum. Sayıları en düşük olanları toplayıp bir düğüm oluşturup , sayılarının toplamını düğümün sayısı olarak kabul edip bir dahaki basamağa geçiyorum. Yine en düşükleri toplayıp düğüm oluşturuyorum. Bu işlemi en sondaki düğüm bir tane oluncaya kadar devam edicek , o düğümün sayısı da text'in bütün karakterin toplam sayısı olacaktır. Bu işlemleri yaparken izlediğimiz yol her bir karakterin 0 ve 1 ler ile nasıl kodlandığını gösterecektir. 0 ve 1 leri takip edersek bir binary tree oluştuğunu göreceksiniz.
Aşağıdaki ekran görüntüsünde input olarak 'dafsderqeereqeaaae' girilmiştir. Üstteki işlem yapılarak her bir karakterin kodlaması şöyle çıkacaktır;
r : 000 , q : 001 , a : 01 , d : 100 , s: 1010 , f : 1011 , e : 11
Output olarak ise : 1000110111010100110000011111000110011101010111
Dikkat ettiyseniz input içinde 'a' ve 'e' en fazla geçen harfler ve sadece 2 bit ile gösterilebiliyor ama 's' ile 'f' sadece bir kez geçiyor. Aşağıdaki binary tree çizimi ile algortmanın mantığını ve yukardaki işlemleri daha rahat anlayabilirsiniz.
Yukarıda encode işlemini yaptık sırada decode işlemi var. 0 ve 1 lerden bir input olucak. Decoder tek tek 0 veya 1 leri alıyor ta ki bir harf ile eşleşene kadar. Tek tek bütün karakterler için yapıyor. Elbette yukarıda çizimini yaptığmız binary tree olmadan 0 ve 1 lerin bizim hiç bir anlamı yok. Hangi harfin ne ile kodlandığnı bilmemiz gerekiyor. Program encode ve decode işlemini program kapandıktan sonra veya başka bir bilgisayarda yapması gerektiğinde 0 ve 1 lerden oluşan dosya haricinde o binary tree'nin de bilgilerinin içerdiği bir dosyaya sahip olması gerekiyor. Ben de bunu XML dosyasında <r>000</r> <q>001</q> şeklinde kaydederek aradaki haberleşmeyi sağladım.
Aşağıdaki ekran görüntüsünde önceki örneğin output'unu tekrar kullanıp bizim orjinal text'imizi geri getirme işlemini gösterdim.
