Programming Assignment 2: Randomized Queues and Deques
题目地址:
http://coursera.cs.princeton.edu/algs4/assignments/queues.html-------------------------------------------------------------------------
正文:
第二周作业要做两个类第一个是使用迭代器iterator的双向队列类
public class Deque<Item> implements Iterable<Item> {
public Deque() // construct an empty deque
public boolean isEmpty() // is the deque empty?
public int size() // return the number of items on the deque
public void addFirst(Item item) // insert the item at the front
public void addLast(Item item) // insert the item at the end
public Item removeFirst() // delete and return the item at the front
public Item removeLast() // delete and return the item at the end
public Iterator<Item> iterator() // return an iterator over items in order from front to end
public static void main(String[] args) // unit testing
}
JAVA的队列与C的一致,这里采用的是线性表实现。
第一个类应该不难,无非就是两侧都可以入队、出队。
相信掌握了单队列的同学很快就可以独立编写出来。
稍微注意一下捕捉和抛出错误,按照题目里给予的方式即可,否则会扣分。
要说一下迭代器的问题。
迭代器照我的理解就是一种方便使用遍历方法的接口。
在iterator里面,我们要实现遍历的方法。
源代码如下:
import java.util.Iterator;
public class Deque<Item> implements Iterable<Item> {
private int N; // number of elements on queue
private Node first; // beginning of queue
private Node last; // end of queue
private class Node {
Item item;
Node pre;
Node next;
}
public Deque(){
first = null;
last = null;
N = 0;
} // construct an empty deque
public boolean isEmpty(){
return N==0;
} // is the deque empty?
public int size(){
return N;
} // return the number of items on the deque
public void addFirst(Item item){
if(item == null) throw new java.lang.NullPointerException();
Node oldfirst = first;
first = new Node();
first.item = item;
//first.pre = null;
first.next=oldfirst;
if (isEmpty()) last = first;
else oldfirst.pre = first;
N++;
} // insert the item at the front
public void addLast(Item item){
if(item == null) throw new java.lang.NullPointerException();
Node oldlast = last;
last = new Node();
last.item = item;
//last.next = null;
last.pre=oldlast;
if (isEmpty()) first = last;
else oldlast.next = last;
N++;
} // insert the item at the end
public Item removeFirst(){
if(isEmpty()) {
throw new java.util.NoSuchElementException("Queue underflow");
}
Item item=first.item;
first=first.next;
N--;
if(isEmpty())
last=null;
else first.pre=null;
return item;
} // delete and return the item at the front
public Item removeLast(){
if(isEmpty()) {
throw new java.util.NoSuchElementException("Queue underflow");
}
Item item=last.item;
last=last.pre;
N--;
if(isEmpty())
first=null;
else last.next=null;
return item;
} // delete and return the item at the end
public Iterator<Item> iterator(){
return new ListIterator();
} // return an iterator over items in order from front to end
private class ListIterator implements Iterator<Item>{
private Node current = first;
public boolean hasNext() { return current != null; }
public void remove() {
throw new java.lang.UnsupportedOperationException();
}
public Item next()
{
if(!hasNext()) throw new java.util.NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
public static void main(String[] args){
Deque<String> deque = new Deque<String> ();
while(!StdIn.isEmpty()) {
String s = StdIn.readString();
if(!s.equals("-")) {
StdOut.println("1->deque.size()=" +deque.size());
deque.addFirst(s);
StdOut.println("2->deque.size()=" +deque.size());
}
else if(!deque.isEmpty()) {
StdOut.println(deque.removeFirst() + " ");
StdOut.println("3->deque.size()=" +deque.size());
}
}
StdOut.println("(" + deque.size() +" left on the deque)");
}
} // unit testing
第二个类是随机队列
public class RandomizedQueue<Item> implements Iterable<Item> {
public RandomizedQueue() // construct an empty randomized queue
public boolean isEmpty() // is the queue empty?
public int size() // return the number of items on the queue
public void enqueue(Item item) // add the item
public Item dequeue() // delete and return a random item
public Item sample() // return (but do not delete) a random item
public Iterator<Item> iterator() // return an independent iterator over items in random order
public static void main(String[] args) // unit testing
}
这个类我是用数组实现的,因为这个类需要进行查找,用线性表显然浪费很多时间。
重点说一下
随机出队的思路:
就是随机抽取数组中的某一项,然后将队末元素赋值给这一项,同时将队末元素删除即可。
代码倒是不难不过我当时真的想了一段时间。
迭代器的代码还是要仔细学习一下,我个人认为以后用到的机会会很多。
源代码如下:
import java.util.Iterator;
public class RandomizedQueue<Item> implements Iterable<Item> {
private Item[] s;
private int N=0;
public RandomizedQueue(){
s = (Item[]) new Object[2];
} // construct an empty randomized queue
public boolean isEmpty(){
return N==0;
} // is the queue empty?
public int size(){
return N;
} // return the number of items on the queue
private void resize(int capacity)
{
Item[] temp = (Item[]) new Object[capacity];
for (int i = 0; i < N; i++)
temp[i] = s[i];
s = temp;
}
public void enqueue(Item item){
if(item == null) throw new java.lang.NullPointerException();
if(N == s.length) resize(2*s.length);
s[N++] = item;
} // add the item
public Item dequeue(){
if(isEmpty()) throw new java.util.NoSuchElementException();
int index = (int) (Math.random()*N);
Item item = s[index];
if(index != N-1) s[index] = s[N-1];
s[N-1] = null;
N--;
if(N>0 && N==s.length/4) resize(s.length/2);
return item;
} // delete and return a random item
public Item sample(){
if(isEmpty()) throw new java.util.NoSuchElementException();
int index = (int) (Math.random()*N);
Item item = s[index];
return item;
} // return (but do not delete) a random item
public Iterator<Item> iterator(){
return new RQIterator();
} // return an independent iterator over items in random order
private class RQIterator implements Iterator<Item> {
private int index = 0;
private Item[] r;
public RQIterator() {
r = (Item[]) new Object[N];
for(int i=0; i<N; i++)
r[i] = s[i];
StdRandom.shuffle(r);
}
public boolean hasNext() {
return index < N;
}
public void remove() {
throw new java.lang.UnsupportedOperationException();
}
public Item next() {
if(!hasNext()) throw new java.util.NoSuchElementException();
Item item = r[index++];
return item;
}
}
public static void main(String[] args){} // unit testing
}