Обновить sk1/compressor.c
This commit is contained in:
		
							parent
							
								
									10cc53b3bb
								
							
						
					
					
						commit
						5ba38bda7b
					
				| @ -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"); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user