From f0ea3294e25bace1cf0cd60dd9be2c6ddcbec53d Mon Sep 17 00:00:00 2001 From: Caitlin Gao Date: Wed, 10 Jul 2019 23:57:08 +0800 Subject: [PATCH] feat(geektime_algo): add 09 queue --- rust/09_queue/array_queue.rs | 65 ++++++++++++++++++++++++++++ rust/09_queue/circle_queue.rs | 55 ++++++++++++++++++++++++ rust/09_queue/linked_list_queue.rs | 69 ++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100644 rust/09_queue/array_queue.rs create mode 100644 rust/09_queue/circle_queue.rs create mode 100644 rust/09_queue/linked_list_queue.rs diff --git a/rust/09_queue/array_queue.rs b/rust/09_queue/array_queue.rs new file mode 100644 index 0000000..e4621b4 --- /dev/null +++ b/rust/09_queue/array_queue.rs @@ -0,0 +1,65 @@ +#[derive(Debug)] +struct ArrayQueue { + queue: Vec, + head: i32, + tail: i32, +} + +impl ArrayQueue { + fn new(n: usize) -> Self { + ArrayQueue { + queue: Vec::with_capacity(n), + head: 0, + tail: 0, + } + } + + fn enqueue(&mut self, num: i32) -> bool { + let c = self.queue.capacity() as i32; + // queue is full + if self.head == 0 && self.tail == c { return false; } + if self.tail == c { + for i in 0..(self.tail-self.head) as usize { + self.queue[i] = self.queue[self.head as usize + i]; + } + self.tail -= self.head; + self.head = 0; + self.queue[self.tail as usize] = num; + } else { + self.queue.push(num); + } + + self.tail += 1; + true + } + + fn dequeue(&mut self) -> i32 { + if self.head == self.tail { return -1; } + + let shift = self.queue[self.head as usize]; + self.head += 1; + shift + } + + fn print_all(&self) { + let mut s = String::from(""); + for i in self.head..self.tail { + s.push(self.queue[i as usize] as u8 as char); + s.push_str("->"); + } + println!("{:?}", s); + } +} + +fn main() { + let mut queue = ArrayQueue::new(3); + queue.enqueue(2); + queue.enqueue(2); + queue.enqueue(2); + queue.enqueue(2); + queue.dequeue(); + queue.dequeue(); + queue.enqueue(4); + queue.dequeue(); + queue.print_all(); +} diff --git a/rust/09_queue/circle_queue.rs b/rust/09_queue/circle_queue.rs new file mode 100644 index 0000000..d263be9 --- /dev/null +++ b/rust/09_queue/circle_queue.rs @@ -0,0 +1,55 @@ +#[derive(Debug)] +struct CircleQueue { + queue: Vec, + head: i32, + tail: i32, + n: i32, +} + +impl CircleQueue { + fn new(n: i32) -> Self { + CircleQueue { + queue: vec![-1; n as usize], + head: 0, + tail: 0, + n: n, + } + } + + fn enqueue(&mut self, num: i32) -> bool { + if (self.tail + 1) % self.n == self.head { return false; } + self.queue[self.tail as usize] = num; + self.tail = (self.tail + 1) % self.n; + true + } + + fn dequeue(&mut self) -> i32 { + if self.head == self.tail { return -1; } + + let shift = self.queue[self.head as usize]; + self.head = (self.head + 1) % self.n; + shift + } + + fn print_all(&self) { + let mut s = String::from(""); + for i in self.head..self.tail { + s.push(self.queue[i as usize] as u8 as char); + s.push_str("->"); + } + println!("{:?}", s); + } +} + +fn main() { + let mut queue = CircleQueue::new(10); + queue.enqueue(2); + queue.enqueue(2); + queue.enqueue(2); + queue.enqueue(2); + queue.dequeue(); + queue.dequeue(); + queue.enqueue(4); + queue.dequeue(); + queue.print_all(); +} diff --git a/rust/09_queue/linked_list_queue.rs b/rust/09_queue/linked_list_queue.rs new file mode 100644 index 0000000..1eaf025 --- /dev/null +++ b/rust/09_queue/linked_list_queue.rs @@ -0,0 +1,69 @@ +#![feature(box_into_raw_non_null)] + +use std::ptr::NonNull; + +#[derive(Debug)] +pub struct LinkedListQueue { + head: Option>, + tail: Option>, +} + +pub struct Node { + next: Option>, + element: i32, +} + +impl Node { + fn new(element: i32) -> Self { + Node { + next: None, + element, + } + } + + fn into_element(self: Box) -> i32 { + self.element + } +} + +impl LinkedListQueue { + pub fn new() -> Self { + LinkedListQueue { + head: None, + tail: None, + } + } + + pub fn dequeue(&mut self) -> i32 { + self.head.map(|node| unsafe { + let node = Box::from_raw(node.as_ptr()); + self.head = node.next; + node + }).map(Node::into_element).unwrap() + } + + pub fn enqueue(&mut self, elt: i32) { + let mut node = Box::new(Node::new(elt)); + unsafe { + node.next = None; + let node = Some(Box::into_raw_non_null(node)); + + match self.tail { + None => self.head = node, + Some(tail) => (*tail.as_ptr()).next = node, + } + + self.tail = node; + } + } +} + +fn main() { + let mut m = LinkedListQueue::new(); + m.enqueue(4); + m.enqueue(4); + m.enqueue(4); + m.dequeue(); + m.dequeue(); + println!("{:?}", m); +}