180 lines
4.7 KiB
Rust
180 lines
4.7 KiB
Rust
use std::collections::HashMap;
|
|
use std::collections::VecDeque;
|
|
|
|
pub struct Node {
|
|
pub val: Option<char>,
|
|
pub l: Option<Box<Node>>,
|
|
pub r: Option<Box<Node>>,
|
|
pub n: i32,
|
|
pub path: String,
|
|
}
|
|
impl PartialEq for Node {
|
|
fn eq(&self, other: &Self) -> bool {
|
|
self.n == other.n
|
|
}
|
|
}
|
|
|
|
impl Eq for Node {}
|
|
|
|
impl PartialOrd for Node {
|
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
|
Some(self.cmp(other))
|
|
}
|
|
}
|
|
|
|
impl Ord for Node {
|
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
|
self.n.cmp(&other.n)
|
|
}
|
|
}
|
|
impl Node {
|
|
pub fn new() -> Self {
|
|
Node {
|
|
val: None,
|
|
l: None,
|
|
r: None,
|
|
n: 0,
|
|
path: String::new(),
|
|
}
|
|
}
|
|
|
|
pub fn set_char(&mut self, v: char) {
|
|
self.val = Some(v);
|
|
}
|
|
|
|
pub fn set_counter(&mut self, n: i32) {
|
|
self.n = n;
|
|
}
|
|
|
|
pub fn insert(&mut self, l: Node, r: Node) {
|
|
self.l = Some(Box::new(l));
|
|
self.r = Some(Box::new(r));
|
|
}
|
|
}
|
|
|
|
pub fn tree_to_map(root: &mut Node, char_to_bin: bool) -> HashMap<String, String> {
|
|
let mut map: HashMap<String, String> = HashMap::new();
|
|
let mut to_do: VecDeque<&mut Node> = VecDeque::new();
|
|
to_do.push_back(root);
|
|
|
|
while let Some(int_root) = to_do.pop_front() {
|
|
if let Some(v) = int_root.val {
|
|
// leaf
|
|
if char_to_bin {
|
|
map.insert(v.to_string(), int_root.path.to_string());
|
|
} else {
|
|
map.insert(int_root.path.to_string(), v.to_string());
|
|
}
|
|
} else {
|
|
// internal
|
|
if let Some(l) = int_root.l.as_mut() {
|
|
l.path = format!("{}0", int_root.path);
|
|
to_do.push_back(l);
|
|
}
|
|
if let Some(r) = int_root.r.as_mut() {
|
|
r.path = format!("{}1", int_root.path);
|
|
to_do.push_back(r);
|
|
}
|
|
}
|
|
}
|
|
|
|
map
|
|
}
|
|
|
|
pub fn create_tree(mut nodes: Vec<Node>) -> Node {
|
|
while nodes.len() > 1 {
|
|
//nodes.sort_by_key(|node| node.n);
|
|
let mut new_root = Node::new();
|
|
let l = nodes.remove(0);
|
|
let r = nodes.remove(0);
|
|
new_root.set_counter(l.n + r.n);
|
|
new_root.insert(l, r);
|
|
//nodes.push(new_root);
|
|
match nodes.binary_search(&new_root) {
|
|
Ok(_) => {}
|
|
Err(pos) => {
|
|
nodes.insert(pos, new_root);
|
|
}
|
|
}
|
|
}
|
|
nodes.pop().unwrap()
|
|
}
|
|
|
|
pub fn tree_to_string(root: &mut Node) -> (String, Vec<char>) {
|
|
let mut tree = String::new();
|
|
let mut chars: Vec<char> = Vec::new();
|
|
let mut to_do: VecDeque<&mut Node> = VecDeque::new();
|
|
to_do.push_back(root);
|
|
|
|
while let Some(n) = to_do.pop_front() {
|
|
match n.val {
|
|
Some(c) => {
|
|
tree.push('0');
|
|
chars.push(c);
|
|
}
|
|
None => {
|
|
tree.push('1');
|
|
if let Some(l) = n.l.as_mut() {
|
|
to_do.push_back(l);
|
|
}
|
|
if let Some(r) = n.r.as_mut() {
|
|
to_do.push_back(r);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
(tree, chars)
|
|
}
|
|
|
|
pub fn read_tree(binary: &str, chars: &Vec<char>) -> Node {
|
|
let mut stack_bin = String::from(binary);
|
|
let mut stack_chars = chars.clone();
|
|
let mut to_do: VecDeque<&mut Node> = VecDeque::new();
|
|
let mut root = Node::new();
|
|
|
|
if stack_bin.remove(0) == '1' {
|
|
root.path = String::from("");
|
|
to_do.push_back(&mut root);
|
|
} else {
|
|
root.val = Some(stack_chars.remove(0));
|
|
root.path = String::from("0");
|
|
return root;
|
|
}
|
|
|
|
while let Some(int_root) = to_do.pop_front() {
|
|
int_root.insert(Node::new(), Node::new());
|
|
if let Some(left) = int_root.l.as_mut() {
|
|
if stack_bin.remove(0) == '1' {
|
|
left.path = String::from("1");
|
|
to_do.push_back(left);
|
|
} else {
|
|
left.path = String::from("0");
|
|
left.val = Some(stack_chars.remove(0));
|
|
}
|
|
}
|
|
if let Some(right) = int_root.r.as_mut() {
|
|
if stack_bin.remove(0) == '1' {
|
|
right.path = String::from("1");
|
|
to_do.push_back(right);
|
|
} else {
|
|
right.path = String::from("0");
|
|
right.val = Some(stack_chars.remove(0));
|
|
}
|
|
}
|
|
}
|
|
root
|
|
}
|
|
pub fn nodes_at_vec(map: HashMap<char, i32>) -> Vec<Node> {
|
|
let mut nodes = Vec::new();
|
|
|
|
for (key, value) in &map {
|
|
let mut node = Node::new();
|
|
node.set_char(*key);
|
|
node.set_counter(*value);
|
|
nodes.push(node);
|
|
}
|
|
nodes.sort();
|
|
nodes
|
|
}
|