![]() |
Huffman Ağacı |
#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: Huffman Kodlaması, huffman kodlaması c kodu, huffman nedir, kayıpsız sıkıştırma, sıkıştırma algoritmalarıi algoritmalar