/**
Solutions for programming assignment 1.
Data structures and algorithms, CS 305 & 503
Spring 2010.
*/
public class
LinkList<E>
implements LinkedSequence<E> {
/**
Insert a new value after an existing value in this linked list.
@param e The existing value in this linked list after which the new value
will be inserted. If e is null, the new value is inserted after the head.
If e occurrs more than once, the new value is inserted after the leftmost
(closest to the head) value.
@param v The new value to insert.
@return true iff the new value was inserted.
*/
private boolean
addAfter(E e, E v) {
if (e == null) {
head = new Link<E>(v, head)
animator.unlink(null, head.next)
animator.link(head, head.next)
animator.link(null, head)
return true
}
Link<E> link = find(e)
if (link == null)
return false
link.next = new Link<E>(v, link.next)
animator.unlink(link, link.next.next)
animator.link(link, link.next)
animator.link(link.next, link.next.next)
return true
}
/**
Determine if this linked list contains a value.
@param v a value.
@return a reference to a link containing v, or null if there's no such
link.
*/
private Link<E>
find(E v) {
for (Link<E> link = head; link != null; link = link.next)
if (link.hasValue(v))
return link
return null
}
/**
Determine if this linked list contains a value.
@param v a value.
@return true iff this linked list contains v.
*/
public boolean
has(E v) {
return find(v) != null
}
/**
Insert a new value after an existing value in this linked list.
@param e The existing value in this linked list after which the new value
will be inserted. If e is null, the new value is inserted after the head.
If e occurrs more than once, the new value is inserted after the leftmost
(closest to the head) value.
@param v The new value to insert.
@return true iff the new value was inserted.
*/
public boolean
insertAfter(E e, E v) {
if (!addAfter(e, v))
return false
count++
return true
}
/**
Determine if this linked list contains any values.
@return true iff this linked list contains no values.
*/
public boolean
isEmpty() {
return head == null
}
/**
Create a new empty linked list.
*/
public LinkList() {
head = null
count = 0
}
/**
Run some tests. Call it with
$ java -ea -classpath public/pa1.jar:. LinkList
*/
public static void
main(String args[]) {
LinkList<Integer> l = new LinkList<Integer>()
l.setAnimator(new NullLSA())
assert l.isEmpty() : "l.isEmpty() failed"
assert l.insertAfter(null, 0) : "l.insertAfter(null, 0) failed."
assert !l.isEmpty() : "!l.isEmpty() failed"
assert l.see() == 0 : "l.see() == 0 failed"
assert l.has(0): "l.has(0) failed"
assert l.insertAfter(null, 1) : "l.insertAfter(null, 1) failed."
assert l.see() == 1 : "l.see() == 1 failed"
assert l.has(0): "l.has(0) failed"
assert l.has(1): "l.has(1) failed"
assert l.remove(1) : "l.remove(1) failed"
assert l.see() == 0 : "l.see() == 0 failed"
assert l.remove(0) : "l.remove(0) failed"
assert l.isEmpty() : "l.isEmpty() failed"
}
/**
Remove a value from this linked list.
@param e The value to remove.
@return true if e was removed from the list, false if e wasn't in the
list.
*/
public boolean
remove(E v) {
if (isEmpty())
return false
if (head.hasValue(v)) {
animator.unlink(null, head)
animator.unlink(head, head.next)
animator.link(null, head.next)
head = head.next
count--
return true
}
for (Link<E> l = head; l.next != null; l = l.next)
if (l.next.hasValue(v)) {
animator.unlink(l, l.next)
animator.unlink(l.next, l.next.next)
animator.link(l, l.next.next)
l.next = l.next.next
count--
return true
}
return false
}
/**
Return the value at this linked list's head.
@return the value at this linked list's head, or null if the list is empty
(note the ambiguity if the value at the list's head is null).
*/
public E
see() {
return isEmpty() ? null : head.value
}
/**
Set this linked list's animataion engine.
@param animator The animator to use in further animations.
*/
public void
setAnimator(LinkedSequenceAnimator animator) {
this.animator = animator
}
/**
Determine the number of values in this linked list.
@return the number of values in this linked list.
*/
public int
size() {
return count
}
/**
The links in the stack.
*/
private static class
Link<E> {
/**
Create a new link.
@param v The new link's value.
@param n The link following the new link (or null).
*/
Link(E v, Link<E> n) {
value = v
next = n;
}
/**
Determine if this link holds a particular value.
@param v The value of interest.
@return true iff this link holds the given value.
*/
boolean
hasValue(E v) {
if (value == null)
return v == null
return value.equals(v)
}
/**
The value held in this link.
*/
final E value
/**
This link's successor, or null if there's no successor.
*/
Link<E> next
}
/**
This linked list's head.
Invariant: count == 0 iff head == null
*/
private Link<E> head
/**
This linked list's animation engine.
invariant: animator != null
*/
LinkedSequenceAnimator animator
/**
The number of values in the linked list.
invariant: count > -1
*/
private int count
}
/**
*/
public class
LinkQueue<E>
implements LinkedSequence<E> {
/**
Determine if this queue contains a value.
@param v a value.
@return true iff this queue contains v.
*/
public boolean
has(E v) {
for (Link<E> link = head; link != null; link = link.next)
if (link.hasValue(v))
return true
return false
}
/**
Insert a new value into this queue.
@param e Should be null or the value currently at the tail.
@param v The value to insert.
@return true if v was inserted, false if e wasn't null and wasn't the
value stored at the tail (if any).
*/
public boolean
insertAfter(E e, E v) {
if ((e != null) && ((tail == null) || !tail.hasValue(e)))
return false
final Link<E> newTail = new Link<E>(v, null)
animator.link(tail, newTail)
if (tail != null)
tail.next = newTail
else
head = newTail
tail = newTail
++count
return true
}
/**
Determine if this queue contains any values.
@return true iff this queue contains no values.
*/
public boolean
isEmpty() {
return head == null
}
/**
Create a new empty queue.
*/
public LinkQueue() {
head = tail = null
count = 0
}
/**
Run some tests. Call it with
$ java -ea -classpath public/pa1.jar:. LinkQueue
*/
public static void
main(String args[]) {
LinkQueue<Integer> q = new LinkQueue<Integer>()
q.setAnimator(new NullLSA())
assert q.isEmpty() : "q.isEmpty() failed"
assert q.insertAfter(null, 0) : "q.insertAfter(null, 0) failed."
assert !q.isEmpty() : "!q.isEmpty() failed"
assert q.see() == 0 : "q.see() == 0 failed"
assert q.insertAfter(null, 1) : "q.insertAfter(null, 1) failed."
assert q.see() == 0 : "q.see() == 0 failed"
assert q.remove(0) : "q.remove(0) failed"
assert q.see() == 1 : "q.see() == 1 failed"
assert q.remove(1) : "q.remove(1) failed"
assert q.isEmpty() : "q.isEmpty() failed"
}
/**
Remove a value from this queue.
@param e The value to remove.
@return true if e was removed from this queue, or false if e wasn't the
value at the queue head.
*/
public boolean
remove(E e) {
if (isEmpty() || !head.hasValue(e))
return false
animator.unlink(null, head)
animator.unlink(head, head.next)
animator.link(null, head.next)
head = head.next
if (--count == 0)
tail = null
return true
}
/**
Return without removing the value at this queue's head.
@return the value at this queue's, or null if the queue is empty.
*/
public E
see() {
if (isEmpty())
return null
return head.value
}
/**
Set this queue's animataion engine.
@param animator The animator to use in further animations.
*/
public void
setAnimator(LinkedSequenceAnimator animator) {
this.animator = animator
}
/**
Determine the number of values in this queue.
@return the number of values in this queue.
*/
public int
size() {
return count
}
/**
The links in the stack.
*/
private static class
Link<E> {
// See LinkList.Link<E> for details.
}
/**
The queue.
invariants:
count == 0 iff head == null
head == null iff tail == null
*/
private Link<E> head, tail
/**
The number of values in the queue.
invariant: count > -1
*/
private int count
/**
This queue's animation engine.
invariant: animator != null
*/
private LinkedSequenceAnimator animator
}
/**
*/
public class
LinkStack<E>
implements LinkedSequence<E> {
/**
Determine if this stack contains a value.
@param v a value.
@return true iff this stack contains v.
*/
public boolean
has(E v) {
for (Link<E> link = head; link != null; link = link.next)
if (link.hasValue(v))
return true
return false
}
/**
Insert a new value into this stack.
@param e Should be null.
@param v The value to insert.
@return true if v was inserted, false if e wasn't null.
*/
public boolean
insertAfter(E e, E v) {
if (e != null)
return false
if (head != null)
animator.unlink(null, head)
head = new Link<E>(v, head)
count++
if (head.next != null)
animator.link(head.next, head.next.next)
animator.link(null, head)
return true
}
/**
Determine if this stack contains any values.
@return true iff this stack contains no values.
*/
public boolean
isEmpty() {
return head == null
}
/**
Create a new empty stack.
*/
public LinkStack() {
head = null
count = 0
}
/**
Run some tests. Call it with
$ java -ea -classpath public/pa1.jar:. LinkStack
*/
public static void
main(String args[]) {
LinkStack<Integer> s = new LinkStack<Integer>()
s.setAnimator(new NullLSA())
assert s != null : "s is null"
assert s.isEmpty() : "s.isEmpty() failed"
assert s.insertAfter(null, 0) : "s.insertAfter(null, 0) failed."
assert !s.isEmpty() : "!s.isEmpty() failed"
assert s.see() == 0 : "s.see() == 0 failed"
assert s.insertAfter(null, 1) : "s.insertAfter(null, 1) failed."
assert s.see() == 1 : "s.see() == 1 failed"
assert s.remove(1) : "s.remove(1) failed"
assert s.see() == 0 : "s.see() == 0 failed"
assert s.remove(0) : "s.remove(0) failed"
assert s.isEmpty() : "s.isEmpty() failed"
}
/**
Remove a value from the stack.
@param e The value to remove.
@return true e was the stack top, false otherwise.
*/
public boolean
remove(E v) {
if (isEmpty() || !head.hasValue(v))
return false
animator.unlink(head, head.next)
animator.unlink(null, head)
animator.link(null, head.next)
head = head.next
count--
return true
}
/**
Return the value at this stack's top.
@return the value at this stack's top, or null if this stack is empty
(note the ambiguity).
*/
public E
see() {
return isEmpty() ? null : head.value
}
/**
Set this stack's animataion engine.
@param animator The animator to use in further animations.
*/
public void
setAnimator(LinkedSequenceAnimator animator) {
this.animator = animator
}
/**
Determine the number of values in this stack.
@return the number of values in this stack.
*/
public int
size() {
return count
}
/**
The links in the stack.
*/
private static class
Link<E> {
// See LinkList.Link<E> for details.
}
/**
The values pushed into this stack.
invariant: count == 0 iff head == null
*/
private Link<E> head
/**
This stack's animation engine.
invariant: animator != null
*/
LinkedSequenceAnimator animator
/**
The number of values in the stack.
invariant: count > -1
*/
private int count
}
syntax highlighted by Code2HTML, v. 0.9.1