Huffman Kodlaması C Kodu

huffman kodlaması ağacı
Huffman Ağacı
Huffman Kodlaması algroritmasının adım adım nasıl oluşturulurduğunu bir önceki yazımızda anlatmıştık. Huffman Kodlama Nedir diye soruyorsunız ilgili yazımızdan faydalanabilirsiniz.

Size aşağıda hazır kodları veriyorum, ama gözünüz korkabilir. Bu kodların çoğu aslında agaç oluşturma ile ilgili esaslara dair fonksiyonları içeriyor. Çünkü Huffman Kodlaması C kodu oluştururken ağaç oluşturmamız ve min heap fonksiyonlarını yazmamız gerekiyordu. Bu yüzden kodlar oldukça uzadı. Elimden geldiğince açıklama satırları ekledim.

Eğer Ağaç Veri Yapısı kavramını bilmiyorsanız kodu anlamanız için konuya çalışmanızı tavsiye ederim.


#include <stdio.h>

#include <stdlib.h>



// Maximum agac yuksekligi

#define MAX_TREE_HT 100



// ********************

// ********************

// algoritmauzmani.blogspot.com

// ********************

// ********************

// daha fazlasi icin bizi ziyaret edin



// Tree node'larindaki bilgileri burada tutuyoruz

struct MinHeapNode

{

    char data;  // karakter girisi

    unsigned freq;  // karakterin sikligi

    struct MinHeapNode *left, *right; // Agacin sol ve sag cocuklari

};



// Burada Huffman Agacinin bilgilerini tutuyoruz

struct MinHeap

{

    unsigned size;    // Agacin boyutu

    unsigned capacity;   // agacin kapasitesi

    struct MinHeapNode **array;  // minheapnode ile olusturulan nodelari tutuyoruz. cift pointer childlar icin.

};



// Bu fonksiyona karakter ve frekans gonderiyoruz, o da bizim icin agac oluşturuyor.



struct MinHeapNode* newNode(char data, unsigned freq)

{

    struct MinHeapNode* temp =

          (struct MinHeapNode*) malloc(sizeof(struct MinHeapNode));

    temp->left = temp->right = NULL;

    temp->data = data;

    temp->freq = freq;

    return temp;

}



// belirtilen kapasitede minheap yapisi olusturuluyor

struct MinHeap* createMinHeap(unsigned capacity)

{

    struct MinHeap* minHeap =

         (struct MinHeap*) malloc(sizeof(struct MinHeap));

    minHeap->size = 0;  // current size is 0

    minHeap->capacity = capacity;

    minHeap->array =

     (struct MinHeapNode**)malloc(minHeap->capacity * sizeof(struct MinHeapNode*));

    return minHeap;

}



// iki node'u swap eden fonksiyon. Agac dengesi icin

void swapMinHeapNode(struct MinHeapNode** a, struct MinHeapNode** b)

{

    struct MinHeapNode* t = *a;

    *a = *b;

    *b = t;

}



// Klasik heapify fonsiyonu, huffmana dair bir şey yok burada.

void minHeapify(struct MinHeap* minHeap, int idx)

{

    int smallest = idx;

    int left = 2 * idx + 1;

    int right = 2 * idx + 2;



    if (left < minHeap->size &&

        minHeap->array[left]->freq < minHeap->array[smallest]->freq)

      smallest = left;



    if (right < minHeap->size &&

        minHeap->array[right]->freq < minHeap->array[smallest]->freq)

      smallest = right;



    if (smallest != idx)

    {

        swapMinHeapNode(&minHeap->array[smallest], &minHeap->array[idx]);

        minHeapify(minHeap, smallest);

    }

}



// Heap boyutu 1 mi degil mi onu kontrol eden fonksiyon

int isSizeOne(struct MinHeap* minHeap)

{

    return (minHeap->size == 1);

}



// En kucuk degere sahip heap node buluyor

struct MinHeapNode* extractMin(struct MinHeap* minHeap)

{

    struct MinHeapNode* temp = minHeap->array[0];

    minHeap->array[0] = minHeap->array[minHeap->size - 1];

    --minHeap->size;

    minHeapify(minHeap, 0);

    return temp;

}



// Min heap'e yeni node ekliyor

void insertMinHeap(struct MinHeap* minHeap, struct MinHeapNode* minHeapNode)

{

    ++minHeap->size;

    int i = minHeap->size - 1;

    while (i && minHeapNode->freq < minHeap->array[(i - 1)/2]->freq)

    {

        minHeap->array[i] = minHeap->array[(i - 1)/2];

        i = (i - 1)/2;

    }

    minHeap->array[i] = minHeapNode;

}



// MinHeap olusturan fonksiyon

void buildMinHeap(struct MinHeap* minHeap)

{

    int n = minHeap->size - 1;

    int i;

    for (i = (n - 1) / 2; i >= 0; --i)

        minHeapify(minHeap, i);

}



// ekrana dizinin degerlerini bastıran fonksiyon

void printArr(int arr[], int n)

{

    int i;

    for (i = 0; i < n; ++i)

        printf("%d", arr[i]);

    printf("\n");

}



// bir nodeun cocugu var mi yok mu onu kontrol ediyor

int isLeaf(struct MinHeapNode* root)

{

    return !(root->left) && !(root->right) ;

}



// girilen karakterlerin boyutuna gore minheap olustuyor.

struct MinHeap* createAndBuildMinHeap(char data[], int freq[], int size)

{

    struct MinHeap* minHeap = createMinHeap(size);

    for (int i = 0; i < size; ++i)

        minHeap->array[i] = newNode(data[i], freq[i]);

    minHeap->size = size;

    buildMinHeap(minHeap);

    return minHeap;

}



// Esas kod kısmı burasi huffman agacini olustuyor.

struct MinHeapNode* buildHuffmanTree(char data[], int freq[], int size)

{

    struct MinHeapNode *left, *right, *top;



    // belirtilen boyutta min heap olusturuyoruz.

    struct MinHeap* minHeap = createAndBuildMinHeap(data, freq, size);



    // dongumuz heap boyutu 1 olmadigi surece donuyor.

    while (!isSizeOne(minHeap))

    {

        // en kucuk frekansa sahip iki karakteri heap ediyoruz.

        left = extractMin(minHeap);

        right = extractMin(minHeap);



        //  iki karakteri toplayip parent node olusturma islemini burada yapiyoruz. a=4 b=5 ise ab=9 olusturmak gibi

        top = newNode('$', left->freq + right->freq);

        top->left = left;

        top->right = right;

        insertMinHeap(minHeap, top);

    }



    // geriye kalan node root node oldugu icin bunu geri donduruyoruz.

    return extractMin(minHeap);

}



// root'dan itibaren tum nodelari ekrana bastiriyoruz.

void printCodes(struct MinHeapNode* root, int arr[], int top)

{

   

    if (root->left)

    {

        arr[top] = 0;

        printCodes(root->left, arr, top + 1);

    }



   

    if (root->right)

    {

        arr[top] = 1;

        printCodes(root->right, arr, top + 1);

    }





    if (isLeaf(root))

    {

        printf("%c: ", root->data);

        printArr(arr, top);

    }

}



// Huffman agacini olusturan temen fonksiyon. karakter, frekans ve boyut degiskenleri aliyor.

void HuffmanCodes(char data[], int freq[], int size)

{

   //  Huffman Agacini olusturduk

   struct MinHeapNode* root = buildHuffmanTree(data, freq, size);



  

   int arr[MAX_TREE_HT], top = 0;

   printCodes(root, arr, top);

}



// Buradan isterseniz dinamik veri girebileceginiz kod da olusturabilirsiniz.

int main()

{

    char arr[] = {'a', 'b', 'c', 'd', 'e', 'f'};

    int freq[] = {5, 9, 12, 13, 16, 45};

    int size = sizeof(arr)/sizeof(arr[0]);

    HuffmanCodes(arr, freq, size);

    return 0;

}


Etiketler: , , , ,