-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhuff.c
More file actions
151 lines (130 loc) · 4.16 KB
/
huff.c
File metadata and controls
151 lines (130 loc) · 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_TREE_HT 100
// Huffman tree node
struct MinHeapNode {
char data;
unsigned freq;
struct MinHeapNode *left, *right;
};
// MinHeap structure
struct MinHeap {
unsigned size;
unsigned capacity;
struct MinHeapNode** array;
};
// Create a new Huffman tree node
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;
}
// Swap function for heap
void swapMinHeapNode(struct MinHeapNode** a, struct MinHeapNode** b) {
struct MinHeapNode* t = *a;
*a = *b;
*b = t;
}
// MinHeapify function
void minHeapify(struct MinHeap* minHeap, int idx) {
int smallest = idx, left = 2 * idx + 1, 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);
}
}
// Extract the 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];
minHeap->size--;
minHeapify(minHeap, 0);
return temp;
}
// Insert a new node into the min heap
void insertMinHeap(struct MinHeap* minHeap, struct MinHeapNode* minHeapNode) {
int i = minHeap->size++;
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;
}
// Build Huffman tree
struct MinHeapNode* buildHuffmanTree(char data[], int freq[], int size) {
struct MinHeap* minHeap = (struct MinHeap*)malloc(sizeof(struct MinHeap));
minHeap->size = size;
minHeap->capacity = size;
minHeap->array = (struct MinHeapNode**)malloc(minHeap->capacity * sizeof(struct MinHeapNode*));
for (int i = 0; i < size; ++i)
minHeap->array[i] = newNode(data[i], freq[i]);
while (minHeap->size != 1) {
struct MinHeapNode* left = extractMin(minHeap);
struct MinHeapNode* right = extractMin(minHeap);
struct MinHeapNode* top = newNode('$', left->freq + right->freq);
top->left = left;
top->right = right;
insertMinHeap(minHeap, top);
}
return extractMin(minHeap);
}
// Print Huffman codes
void printCodes(struct MinHeapNode* root, int arr[], int top, FILE *treeFile) {
if (root->left) {
arr[top] = 0;
printCodes(root->left, arr, top + 1, treeFile);
}
if (root->right) {
arr[top] = 1;
printCodes(root->right, arr, top + 1, treeFile);
}
if (!(root->left) && !(root->right)) {
fprintf(treeFile, "%c %d\n", root->data, root->freq);
printf("%c: ", root->data);
for (int i = 0; i < top; i++) printf("%d", arr[i]);
printf("\n");
}
}
// Read text from file and count character frequencies
void readFileAndBuildHuffman(const char *filename) {
FILE *fp = fopen(filename, "r");
if (!fp) {
printf("Error opening file!\n");
return;
}
int freq[256] = {0};
char ch;
while ((ch = fgetc(fp)) != EOF)
freq[(unsigned char)ch]++;
fclose(fp);
int size = 0;
char data[256];
int newFreq[256];
for (int i = 0; i < 256; i++) {
if (freq[i] > 0) {
data[size] = (char)i;
newFreq[size] = freq[i];
size++;
}
}
struct MinHeapNode* root = buildHuffmanTree(data, newFreq, size);
FILE *treeFile = fopen("tree_output.txt", "w");
int arr[MAX_TREE_HT];
printCodes(root, arr, 0, treeFile);
fclose(treeFile);
printf("Huffman tree saved to tree_output.txt\n");
}
int main() {
char filename[100];
printf("Enter filename containing text: ");
scanf("%s", filename);
readFileAndBuildHuffman(filename);
return 0;
}