50250. Huffman Coding
難度:5/5
用助教的方法,每一步都qsort()一遍的話,會TLE,所以在合併樹的時候要insertion進去才不會耗太多時間。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#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "huffmanTree.h"
// typedef struct Node {
// char symbol[SYM_MAX_LEN];
// int frequency;
// struct Node *left, *right;
// } Node;
static inline Node* new_node(int f, Node* l, Node* r){
Node* n = (Node*) malloc(sizeof(Node));
n->frequency = f;
n->left = l;
n->right = r;
return n;
}
int cmp(const void* aa, const void* bb){ // a < b than 1
Node* a = *(Node**)aa;
Node* b = *(Node**)bb;
if(a->frequency != b->frequency) return a->frequency > b->frequency ? 1 : -1;
else return strcmp(a->symbol, b->symbol);
}
int rev_cmp(const void* a, const void* b){
return -cmp(a, b);
}
Node* buildHuffmanTree(char* s[SYM_MAX_NUM], int n){
Node* arr[100000]; int len_arr = 0;
for(int i = 0; i < n; i++){
int idx = -1;
for(int j = 0; j < len_arr; j++){
if(strcmp(s[i], arr[j]->symbol) == 0){
idx = j; break;
}
}
if(idx == -1){
Node* n = new_node(1, NULL, NULL);
strcpy(n->symbol, s[i]);
arr[len_arr++] = n;
}
else{
arr[idx]->frequency += 1;
}
}
qsort(arr, len_arr, sizeof(Node*), rev_cmp);
while(len_arr > 1){
// for(int i = 0; i < len_arr; i++) printf("%s %d, ", arr[i]->symbol, arr[i]->frequency); printf("\n");
Node* temp = new_node(arr[len_arr - 2]->frequency + arr[len_arr - 1]->frequency,
arr[len_arr - 2], arr[len_arr - 1]);
if(strcmp(arr[len_arr - 2]->symbol, arr[len_arr - 1]->symbol) < 0) strcpy(temp->symbol, arr[len_arr - 2]->symbol);
else strcpy(temp->symbol, arr[len_arr - 1]->symbol);
// printf("merging %s %d, %s %d\n", arr[len_arr - 2]->symbol, arr[len_arr - 2]->frequency, arr[len_arr - 1]->symbol, arr[len_arr - 1]->frequency);
// printf("get %s %d\n", temp->symbol, temp->frequency);
int insert_idx = 0;
for(int i = len_arr - 3; i >= 0; i--){
if(cmp(&arr[i], &temp) < 0) continue;
else{
insert_idx = i + 1;
break;
}
}
for(int i = len_arr - 2; i > insert_idx; i--) arr[i] = arr[i - 1];
arr[insert_idx] = temp;
len_arr--;
// for(int i = 0; i < len_arr; i++) printf("%s %d, ", arr[i]->symbol, arr[i]->frequency); printf("\n");
// printf("====================================================\n");
}
return arr[0];
}