use vec_arena::Arena;
const NULL: usize = !0;
struct Node<T> {
parent: usize,
children: [usize; 2],
value: T,
}
impl<T> Node<T> {
fn new(value: T) -> Node<T> {
Node {
parent: NULL,
children: [NULL, NULL],
value: value,
}
}
}
struct Splay<T> {
arena: Arena<Node<T>>,
root: usize,
}
impl<T: Ord> Splay<T> {
fn new() -> Splay<T> {
Splay {
arena: Arena::new(),
root: NULL,
}
}
#[inline(always)]
fn link(&mut self, p: usize, c: usize, dir: usize) {
self.arena[p].children[dir] = c;
if c != NULL {
self.arena[c].parent = p;
}
}
#[inline(always)]
fn rotate(&mut self, p: usize, c: usize) {
let g = self.arena[p].parent;
let dir = if self.arena[p].children[0] == c { 0 } else { 1 };
let t = self.arena[c].children[dir ^ 1];
self.link(p, t, dir);
self.link(c, p, dir ^ 1);
if g == NULL {
self.root = c;
self.arena[c].parent = NULL;
} else {
let dir = if self.arena[g].children[0] == p { 0 } else { 1 };
self.link(g, c, dir);
}
}
fn splay(&mut self, c: usize) {
loop {
let p = self.arena[c].parent;
if p == NULL {
break;
}
let g = self.arena[p].parent;
if g == NULL {
self.rotate(p, c);
break;
}
if (self.arena[g].children[0] == p) == (self.arena[p].children[0] == c) {
self.rotate(g, p);
self.rotate(p, c);
} else {
self.rotate(p, c);
self.rotate(g, c);
}
}
}
fn insert(&mut self, value: T) {
let n = self.arena.insert(Node::new(value));
if self.root == NULL {
self.root = n;
} else {
let mut p = self.root;
loop {
let dir = if self.arena[n].value < self.arena[p].value {
0
} else {
1
};
let c = self.arena[p].children[dir];
if c == NULL {
self.link(p, n, dir);
self.splay(n);
break;
}
p = c;
}
}
}
fn print(&self, node: usize, indent: usize)
where
T: std::fmt::Display,
{
if node != NULL {
self.print(self.arena[node].children[0], indent + 3);
println!("{:width$}{}", "", self.arena[node].value, width = indent);
self.print(self.arena[node].children[1], indent + 3);
}
}
}
fn main() {
let mut splay = Splay::new();
let mut num = 1u32;
for _ in 0..30 {
num = num.wrapping_mul(17).wrapping_add(255);
splay.insert(num);
}
splay.print(splay.root, 0);
}