diff --git a/sk1/compressor.c b/sk1/compressor.c index ea88d86..b7c6c43 100644 --- a/sk1/compressor.c +++ b/sk1/compressor.c @@ -4,76 +4,46 @@ #define MAX_TREE_HT 256 -// Узел дерева Хаффмана +// A Huffman tree node struct MinHeapNode { unsigned char data; unsigned freq; struct MinHeapNode *left, *right; }; -// Минкуча +// A MinHeap struct MinHeap { unsigned size; unsigned capacity; struct MinHeapNode** array; }; -// Функция для создания нового узла +// Function to create a new node struct MinHeapNode* createNode(unsigned char data, unsigned freq) { struct MinHeapNode* temp = (struct MinHeapNode*)malloc(sizeof(struct MinHeapNode)); - if (!temp) { - perror("Ошибка выделения памяти для узла дерева"); - exit(EXIT_FAILURE); - } temp->data = data; temp->freq = freq; temp->left = temp->right = NULL; return temp; } -// Функция для создания Минкучи +// Function to create a MinHeap struct MinHeap* createMinHeap(unsigned capacity) { struct MinHeap* minHeap = (struct MinHeap*)malloc(sizeof(struct MinHeap)); - if (!minHeap) { - perror("Ошибка выделения памяти для Минкучи"); - exit(EXIT_FAILURE); - } minHeap->size = 0; minHeap->capacity = capacity; minHeap->array = (struct MinHeapNode**)malloc(minHeap->capacity * sizeof(struct MinHeapNode*)); - if (!minHeap->array) { - perror("Ошибка выделения памяти для массива Минкучи"); - free(minHeap); - exit(EXIT_FAILURE); - } return minHeap; } -// Функция для освобождения памяти дерева -void freeHuffmanTree(struct MinHeapNode* root) { - if (!root) return; - freeHuffmanTree(root->left); - freeHuffmanTree(root->right); - free(root); -} - -// Освобождение памяти массива кодов -void freeCodes(char** codes) { - for (int i = 0; i < 256; i++) { - if (codes[i]) { - free(codes[i]); - } - } -} - -// Swap +// Swap function void swapMinHeapNode(struct MinHeapNode** a, struct MinHeapNode** b) { struct MinHeapNode* t = *a; *a = *b; *b = t; } -// MinHeapify +// MinHeapify function void minHeapify(struct MinHeap* minHeap, int idx) { int smallest = idx; int left = 2 * idx + 1; @@ -91,7 +61,7 @@ void minHeapify(struct MinHeap* minHeap, int idx) { } } -// Извлечение минимального узла +// Extract minimum value node from heap struct MinHeapNode* extractMin(struct MinHeap* minHeap) { struct MinHeapNode* temp = minHeap->array[0]; minHeap->array[0] = minHeap->array[minHeap->size - 1]; @@ -100,11 +70,10 @@ struct MinHeapNode* extractMin(struct MinHeap* minHeap) { return temp; } -// Вставка нового узла в Минкучу +// Insert a new node to MinHeap 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; @@ -112,39 +81,47 @@ void insertMinHeap(struct MinHeap* minHeap, struct MinHeapNode* minHeapNode) { minHeap->array[i] = minHeapNode; } -// Создание и построение Минкучи +// Build the MinHeap +void buildMinHeap(struct MinHeap* minHeap) { + int n = minHeap->size - 1; + for (int i = (n - 1) / 2; i >= 0; --i) + minHeapify(minHeap, i); +} + +// Check if size is 1 +int isSizeOne(struct MinHeap* minHeap) { + return (minHeap->size == 1); +} + +// Create and build a MinHeap struct MinHeap* createAndBuildMinHeap(unsigned char data[], int freq[], int size) { struct MinHeap* minHeap = createMinHeap(size); for (int i = 0; i < size; ++i) minHeap->array[i] = createNode(data[i], freq[i]); minHeap->size = size; - for (int i = (minHeap->size - 2) / 2; i >= 0; --i) - minHeapify(minHeap, i); + buildMinHeap(minHeap); return minHeap; } -// Построение дерева Хаффмана +// Build Huffman Tree struct MinHeapNode* buildHuffmanTree(unsigned char data[], int freq[], int size) { struct MinHeapNode *left, *right, *top; struct MinHeap* minHeap = createAndBuildMinHeap(data, freq, size); - while (minHeap->size > 1) { + while (!isSizeOne(minHeap)) { left = extractMin(minHeap); right = extractMin(minHeap); top = createNode('$', left->freq + right->freq); top->left = left; top->right = right; + insertMinHeap(minHeap, top); } - - struct MinHeapNode* root = extractMin(minHeap); - free(minHeap->array); - free(minHeap); - return root; + return extractMin(minHeap); } -// Сохранение кодов +// Print Huffman Codes to a map void storeCodes(struct MinHeapNode* root, char** codes, char* currentCode, int top) { if (root->left) { currentCode[top] = '0'; @@ -157,14 +134,9 @@ void storeCodes(struct MinHeapNode* root, char** codes, char* currentCode, int t if (!(root->left) && !(root->right)) { currentCode[top] = '\0'; codes[root->data] = strdup(currentCode); - if (!codes[root->data]) { - perror("Ошибка выделения памяти для кодов"); - exit(EXIT_FAILURE); - } } } - // Compress the input file using Huffman Coding int compressFile(const char* input_file_name, const char* output_file_name) { FILE* inputFile = fopen(input_file_name, "rb"); @@ -225,7 +197,7 @@ int compressFile(const char* input_file_name, const char* output_file_name) { byte <<= (8 - bitCount); fwrite(&byte, sizeof(unsigned char), 1, outputFile); } - freeHuffmanTree(root); + fclose(inputFile); fclose(outputFile); return 0; @@ -278,7 +250,7 @@ int decompressFile(const char* input_file_name, const char* output_file_name) { } } } - freeHuffmanTree(root); + fclose(inputFile); fclose(outputFile); return 0;