diff --git a/sk1/compressor.c b/sk1/compressor.c index e04927a..ea88d86 100644 --- a/sk1/compressor.c +++ b/sk1/compressor.c @@ -4,46 +4,76 @@ #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; } -// Swap function +// Функция для освобождения памяти дерева +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 void swapMinHeapNode(struct MinHeapNode** a, struct MinHeapNode** b) { struct MinHeapNode* t = *a; *a = *b; *b = t; } -// MinHeapify function +// MinHeapify void minHeapify(struct MinHeap* minHeap, int idx) { int smallest = idx; int left = 2 * idx + 1; @@ -61,7 +91,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]; @@ -70,10 +100,11 @@ 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; @@ -81,66 +112,39 @@ 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; - buildMinHeap(minHeap); + for (int i = (minHeap->size - 2) / 2; i >= 0; --i) + minHeapify(minHeap, i); return minHeap; } -// Build Huffman Tree -void freeHuffmanTree(struct MinHeapNode* root) { - if (root == NULL) { - return; - } - freeHuffmanTree(root->left); - freeHuffmanTree(root->right); - free(root); -} - -// Build Huffman Tree with memory management +// Построение дерева Хаффмана struct MinHeapNode* buildHuffmanTree(unsigned char data[], int freq[], int size) { struct MinHeapNode *left, *right, *top; struct MinHeap* minHeap = createAndBuildMinHeap(data, freq, size); - while (!isSizeOne(minHeap)) { + while (minHeap->size > 1) { left = extractMin(minHeap); right = extractMin(minHeap); - // Create a new internal node with frequency equal to the sum of the two nodes top = createNode('$', left->freq + right->freq); top->left = left; top->right = right; - insertMinHeap(minHeap, top); } - // Extract the final node, which is the root of the Huffman tree struct MinHeapNode* root = extractMin(minHeap); - - // Free the MinHeap structure free(minHeap->array); free(minHeap); - return root; } -// Print Huffman Codes to a map +// Сохранение кодов void storeCodes(struct MinHeapNode* root, char** codes, char* currentCode, int top) { if (root->left) { currentCode[top] = '0'; @@ -152,11 +156,15 @@ void storeCodes(struct MinHeapNode* root, char** codes, char* currentCode, int t } if (!(root->left) && !(root->right)) { currentCode[top] = '\0'; - if (root->data < 256) { // Ensure data is within bounds - codes[root->data] = strdup(currentCode); + 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");