use std::collections::{BinaryHeap, HashMap};
use std::cmp::Ordering;
#[derive(Eq, PartialEq)]
struct Node {
freq: usize,
char_opt: Option<char>,
left: Option<Box<Node>>,
right: Option<Box<Node>>,
}
impl Ord for Node {
fn cmp(&self, other: &Self) -> Ordering {
// Reverse order for min-heap behavior
other.freq.cmp(&self.freq)
}
}
impl PartialOrd for Node {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
fn build_huffman_tree(freq_map: &HashMap<char, usize>) -> Option<Box<Node>> {
let mut heap = BinaryHeap::new();
// Create leaf nodes for each character
for (&ch, &freq) in freq_map {
heap.push(Node { freq, char_opt: Some(ch), left: None, right: None });
}
// Combine nodes until one tree remains
while heap.len() > 1 {
let right = heap.pop().unwrap();
let left = heap.pop().unwrap();
let merged = Node {
freq: left.freq + right.freq,
char_opt: None,
left: Some(Box::new(left)),
right: Some(Box::new(right)),
};
heap.push(merged);
}
heap.pop().map(Box::new)
}
fn generate_codes(node: &Option<Box<Node>>, prefix: String, codes: &mut HashMap<char, String>) {
if let Some(n) = node {
if let Some(ch) = n.char_opt {
codes.insert(ch, prefix);
} else {
generate_codes(&n.left, format!("{}0", prefix), codes);
generate_codes(&n.right, format!("{}1", prefix), codes);
}
}
}
fn main() {
let freq_map = HashMap::from([
('A', 5), ('B', 9), ('C', 12), ('D', 13), ('E', 16), ('F', 45)
]);
let tree = build_huffman_tree(&freq_map);
let mut codes = HashMap::new();
generate_codes(&tree, String::new(), &mut codes);
let mut chars: Vec<char> = codes.keys().copied().collect();
chars.sort();
for ch in chars {
println!("{}: {}", ch, codes[&ch]);
}
}combine two smallest nodes repeatedly to build tree
let left = heap.pop().unwrap();
pop smallest node from heap
let right = heap.pop().unwrap();
pop next smallest node from heap
let merged = Node { freq: left.freq + right.freq, ... };
create new parent node with combined frequency
push merged node back to heap to continue building tree
if let Some(ch) = n.char_opt { codes.insert(ch, prefix); } else { ... }
assign code to leaf node or recurse for internal nodes
A: 1100
B: 1101
C: 100
D: 101
E: 111
F: 0