Обновить sk1/compressor.c
This commit is contained in:
		
							parent
							
								
									5ba38bda7b
								
							
						
					
					
						commit
						4f7f2b98c9
					
				| @ -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,13 +134,8 @@ 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) { | ||||
| @ -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; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user