1
1
package compressor
2
2
3
- import (
4
- "container/heap"
5
- )
6
-
7
3
// Node represents a node in the Huffman tree
8
4
type Node struct {
9
- char rune // Character stored in the node
10
- freq int // Frequency of the character
11
- left * Node // Left child node
12
- right * Node // Right child node
5
+ char rune // Character stored in the node
6
+ freq int // Frequency of the character
7
+ left * Node // Left child node
8
+ right * Node // Right child node
13
9
}
14
10
15
- // PriorityQueue implements heap.Interface and holds Nodes
11
+ // PriorityQueue implements a priority queue for Nodes
16
12
type PriorityQueue []* Node
17
13
18
14
// Len returns the number of items in the priority queue
@@ -29,12 +25,12 @@ func (pq PriorityQueue) Swap(i, j int) {
29
25
}
30
26
31
27
// Push adds an item (Node) to the priority queue
32
- func (pq * PriorityQueue ) Push (x interface {} ) {
33
- * pq = append (* pq , x .( * Node ) )
28
+ func (pq * PriorityQueue ) Push (x * Node ) {
29
+ * pq = append (* pq , x )
34
30
}
35
31
36
32
// Pop removes and returns the highest priority item (Node) from the priority queue
37
- func (pq * PriorityQueue ) Pop () interface {} {
33
+ func (pq * PriorityQueue ) Pop () * Node {
38
34
old := * pq
39
35
n := len (old )
40
36
item := old [n - 1 ]
@@ -50,27 +46,55 @@ func buildHuffmanTree(freq map[rune]int) *Node {
50
46
pq [i ] = & Node {char : char , freq : f }
51
47
i ++
52
48
}
53
- heap . Init ( & pq )
49
+ buildMinHeap ( pq )
54
50
55
51
for len (pq ) > 1 {
56
- left := heap .Pop (& pq ).( * Node )
57
- right := heap .Pop (& pq ).( * Node )
52
+ left := pq .Pop ()
53
+ right := pq .Pop ()
58
54
59
55
internal := & Node {
60
56
char : '\x00' , // internal node character
61
57
freq : left .freq + right .freq ,
62
58
left : left ,
63
59
right : right ,
64
60
}
65
- heap .Push (& pq , internal )
61
+ pq .Push (internal )
66
62
}
67
63
68
64
if len (pq ) > 0 {
69
- return heap .Pop (& pq ).( * Node ) // root of Huffman tree
65
+ return pq .Pop () // root of Huffman tree
70
66
}
71
67
return nil
72
68
}
73
69
70
+ // buildMinHeap builds a min-heap for the priority queue
71
+ func buildMinHeap (pq PriorityQueue ) {
72
+ n := len (pq )
73
+ for i := n / 2 - 1 ; i >= 0 ; i -- {
74
+ heapify (pq , n , i )
75
+ }
76
+ }
77
+
78
+ // heapify maintains the heap property of the priority queue
79
+ func heapify (pq PriorityQueue , n , i int ) {
80
+ smallest := i
81
+ left := 2 * i + 1
82
+ right := 2 * i + 2
83
+
84
+ if left < n && pq [left ].freq < pq [smallest ].freq {
85
+ smallest = left
86
+ }
87
+
88
+ if right < n && pq [right ].freq < pq [smallest ].freq {
89
+ smallest = right
90
+ }
91
+
92
+ if smallest != i {
93
+ pq .Swap (i , smallest )
94
+ heapify (pq , n , smallest )
95
+ }
96
+ }
97
+
74
98
// buildHuffmanCodes builds Huffman codes (bit strings) for each character
75
99
func buildHuffmanCodes (root * Node ) map [rune ]string {
76
100
codes := make (map [rune ]string )
0 commit comments