2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -1,16 +1,25 @@
{{Data structure}}
[[File:Fifo.gif|frame|right|Illustration of FIFO behavior]]
;Task:
Implement a FIFO queue.
Elements are added at one side and popped from the other in the order of insertion.
Operations:
* push (aka ''enqueue'') - add element
* pop (aka ''dequeue'') - pop first element
* empty - return truth value when empty
*   push   (aka ''enqueue'')   - add element
*   pop     (aka ''dequeue'')   - pop first element
*   empty   - return truth value when empty
Errors:
* handle the error of trying to pop from an empty queue (behavior depends on the language and platform)
*   handle the error of trying to pop from an empty queue (behavior depends on the language and platform)
;See:
*   [[Queue/Usage]]   for the built-in FIFO or queue of your language or standard library.
See [[Queue/Usage]] for the built-in FIFO or queue of your language or standard library.
{{Template:See also lists}}
<br><br>

View file

@ -0,0 +1,42 @@
0
field: list-next
field: list-val
constant list-struct
: insert ( x list-addr -- )
list-struct allocate throw >r
swap r@ list-val !
dup @ r@ list-next !
r> swap ! ;
: remove ( list-addr -- x )
>r r@ @ ( list-node )
r@ @ dup list-val @ ( list-node x )
swap list-next @ r> !
swap free throw ;
0
field: queue-last \ points to the last entry (head of the list)
field: queue-nextaddr \ points to the pointer to the next-inserted entry
constant queue-struct
: init-queue ( queue -- )
>r 0 r@ queue-last !
r@ queue-last r> queue-nextaddr ! ;
: make-queue ( -- queue )
queue-struct allocate throw dup init-queue ;
: empty? ( queue -- f )
queue-last @ 0= ;
: enqueue ( x queue -- )
dup >r queue-nextaddr @ insert
r@ queue-nextaddr @ @ list-next r> queue-nextaddr ! ;
: dequeue ( queue -- x )
dup empty? abort" dequeue applied to an empty queue"
dup queue-last remove ( queue x )
over empty? if
over init-queue then
nip ;

View file

@ -1,21 +1,20 @@
Enqueue := function(v, x)
Add(v[1], x);
Add(v[1], x);
end;
Dequeue := function(v)
local n, x;
n := Size(v[2]);
if n = 0 then
v[2] := Reversed(v[1]);
v[1] := [ ];
n := Size(v[2]);
if n = 0 then
return fail;
fi;
fi;
return Remove(v[2], n);
if IsEmpty(v[2]) then
if IsEmpty(v[1]) then
return fail;
else
v[2] := Reversed(v[1]);
v[1] := [];
fi;
fi;
return Remove(v[2]);
end;
# a new queue
v := [[], []];

View file

@ -1,15 +1,15 @@
my @queue does FIFO;
say @queue.is-empty; # -> Bool::True
say @queue.enqueue: <A B C>; # -> 3
say @queue.enqueue: Any; # -> 1
say @queue.enqueue: 7, 8; # -> 2
say @queue.is-empty; # -> Bool::False
say @queue.dequeue; # -> A
say @queue.elems; # -> 5
say @queue.dequeue; # -> B
say @queue.is-empty; # -> Bool::False
say @queue.enqueue('OHAI!'); # -> 1
say @queue.dequeue until @queue.is-empty; # -> C \n Any() \n 7 \n 8 \n OHAI!
say @queue.is-empty; # -> Bool::True
say @queue.dequeue; # ->
say @queue.is-empty; # -> Bool::True
for <A B C> -> $i { say @queue.enqueue: $i } # 1 \n 1 \n 1
say @queue.enqueue: Any; # -> 1
say @queue.enqueue: 7, 8; # -> 2
say @queue.is-empty; # -> Bool::False
say @queue.dequeue; # -> A
say @queue.elems; # -> 4
say @queue.dequeue; # -> B
say @queue.is-empty; # -> Bool::False
say @queue.enqueue('OHAI!'); # -> 1
say @queue.dequeue until @queue.is-empty; # -> C \n Any() \n [7 8] \n OHAI!
say @queue.is-empty; # -> Bool::True
say @queue.dequeue; # ->

View file

@ -0,0 +1,17 @@
$Q = New-Object System.Collections.Queue
$Q.Enqueue( 1 )
$Q.Enqueue( 2 )
$Q.Enqueue( 3 )
$Q.Dequeue()
$Q.Dequeue()
$Q.Count -eq 0
$Q.Dequeue()
$Q.Count -eq 0
try
{ $Q.Dequeue() }
catch [System.InvalidOperationException]
{ If ( $_.Exception.Message -eq 'Queue empty.' ) { 'Caught error' } }

View file

@ -0,0 +1,13 @@
use std::collections::VecDeque;
fn main() {
let mut stack = VecDeque::new();
stack.push_back("Element1");
stack.push_back("Element2");
stack.push_back("Element3");
assert_eq!(Some(&"Element1"), stack.front());
assert_eq!(Some("Element1"), stack.pop_front());
assert_eq!(Some("Element2"), stack.pop_front());
assert_eq!(Some("Element3"), stack.pop_front());
assert_eq!(None, stack.pop_front());
}

View file

@ -0,0 +1,124 @@
use std::ptr;
pub struct Queue<T> {
head: Link<T>,
tail: *mut Item<T>, // Raw, C-like pointer. Cannot be guaranteed safe
}
type Link<T> = Option<Box<Item<T>>>;
struct Item<T> {
elem: T,
next: Link<T>,
}
pub struct IntoIter<T>(Queue<T>);
pub struct Iter<'a, T:'a> {
next: Option<&'a Item<T>>,
}
pub struct IterMut<'a, T: 'a> {
next: Option<&'a mut Item<T>>,
}
impl<T> Queue<T> {
pub fn new() -> Self {
Queue { head: None, tail: ptr::null_mut() }
}
pub fn enqueue(&mut self, elem: T) {
let mut new_tail = Box::new(Item {
elem: elem,
next: None,
});
let raw_tail: *mut _ = &mut *new_tail;
if !self.tail.is_null() {
unsafe {
(*self.tail).next = Some(new_tail);
}
} else {
self.head = Some(new_tail);
}
self.tail = raw_tail;
}
pub fn dequeue(&mut self) -> Option<T> {
self.head.take().map(|head| {
let head = *head;
self.head = head.next;
if self.head.is_none() {
self.tail = ptr::null_mut();
}
head.elem
})
}
pub fn peek(&self) -> Option<&T> {
self.head.as_ref().map(|item| {
&item.elem
})
}
pub fn peek_mut(&mut self) -> Option<&mut T> {
self.head.as_mut().map(|item| {
&mut item.elem
})
}
pub fn into_iter(self) -> IntoIter<T> {
IntoIter(self)
}
pub fn iter(&self) -> Iter<T> {
Iter { next: self.head.as_ref().map(|item| &**item) }
}
pub fn iter_mut(&mut self) -> IterMut<T> {
IterMut { next: self.head.as_mut().map(|item| &mut **item) }
}
}
impl<T> Drop for Queue<T> {
fn drop(&mut self) {
let mut cur_link = self.head.take();
while let Some(mut boxed_item) = cur_link {
cur_link = boxed_item.next.take();
}
}
}
impl<T> Iterator for IntoIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.0.dequeue()
}
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.next.map(|item| {
self.next = item.next.as_ref().map(|item| &**item);
&item.elem
})
}
}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
self.next.take().map(|item| {
self.next = item.next.as_mut().map(|item| &mut **item);
&mut item.elem
})
}
}