Coursera-Algorithms-4
Github仓库:
https://github.com/shuhai65/Coursera-Algorithms-4
Coursera: Algorithms I & II
https://www.coursera.org/learn/algorithms-part1
https://www.coursera.org/learn/algorithms-part2
编程作业: Queues
Deque用链表做即可,就是一个双向队列,模仿栈和队列的实现。
RandomizedQueue随机队列比较推荐用数组做,我这里写的是用链表实现的,关于用数组实现的我就不贴了,可以参考https://www.cnblogs.com/mingyueanyao/p/10088467.html中的实现。
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Deque<Item> implements Iterable<Item> {
private final Node<Item> head;
private final Node<Item> tail;
// private Node prev = null;
private int n;
private static class Node<Item> {
private Item item;
private Deque.Node<Item> next;
private Deque.Node<Item> prev;
private Node() {
}
}
// construct an empty deque
public Deque() {
n = 0;
head = new Node<>();
tail = new Node<>();
head.item = null;
tail.item = null;
head.prev = null;
tail.prev = head;
head.next = tail;
tail.next = null;
}
// is the deque empty?
public boolean isEmpty() {
return n == 0;
}
// return the number of items on the deque
public int size() {
return n;
}
// add the item to the front
public void addFirst(Item item) {
if (item == null) throw new IllegalArgumentException("item is null");
Node<Item> oldFirst = head.next;
Node<Item> first = new Node<>();
first.item = item;
first.next = oldFirst;
first.prev = head;
oldFirst.prev = first;
head.next = first;
n++;
}
// add the item to the back
public void addLast(Item item) {
if (item == null) throw new IllegalArgumentException("item is null");
Node<Item> oldLast = tail.prev;
Node<Item> last = new Node<>();
last.item = item;
last.next = tail;
last.prev = oldLast;
tail.prev = last;
oldLast.next = last;
n++;
}
// remove and return the item from the front
public Item removeFirst() {
if (isEmpty()) throw new NoSuchElementException("the deque is empty.");
Node<Item> oldFirst = head.next;
Node<Item> first = oldFirst.next;
Item fistItem = oldFirst.item;
head.next = first;
first.prev = head;
n--;
return fistItem;
}
// remove and return the item from the back
public Item removeLast() {
if (isEmpty()) throw new NoSuchElementException("the deque is empty.");
Node<Item> oldLast = tail.prev;
Node<Item> last = oldLast.prev;
Item item = oldLast.item;
tail.prev = last;
last.next = tail;
n--;
return item;
}
// return an iterator over items in order from front to back
public Iterator<Item> iterator() {
return new LinkedIterator(this.head);
}
private class LinkedIterator implements Iterator<Item> {
private Deque.Node<Item> current;
public LinkedIterator(Deque.Node<Item> head) {
this.current = head.next;
}
public boolean hasNext() {
return this.current != tail;
}
public void remove() {
throw new UnsupportedOperationException();
}
public Item next() {
if (!this.hasNext()) {
throw new NoSuchElementException();
} else {
Item item = this.current.item;
this.current = this.current.next;
return item;
}
}
}
// unit testing (required)
public static void main(String[] args) {
Deque<String> deque = new Deque<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
deque.addFirst(item);
}
StdOut.println("size of deque = " + deque.size());
for (String s : deque) {
StdOut.println(s);
}
}
}
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdRandom;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class RandomizedQueue<Item> implements Iterable<Item> {
private final Node<Item> head;
private final Node<Item> tail;
private int n;
private static class Node<Item> {
private Item item;
private RandomizedQueue.Node<Item> next;
private RandomizedQueue.Node<Item> prev;
private Node() {
}
}
// construct an empty randomized queue
public RandomizedQueue() {
n = 0;
head = new RandomizedQueue.Node<>();
tail = new RandomizedQueue.Node<>();
head.item = null;
tail.item = null;
head.prev = null;
tail.prev = head;
head.next = tail;
tail.next = null;
}
// is the randomized queue empty?
public boolean isEmpty() {
return n == 0;
}
// return the number of items on the randomized queue
public int size() {
return n;
}
// add the item
public void enqueue(Item item) {
if (item == null) throw new IllegalArgumentException("item is null");
Node<Item> oldLast = tail.prev;
Node<Item> last = new Node<>();
last.item = item;
last.next = tail;
last.prev = oldLast;
tail.prev = last;
oldLast.next = last;
n++;
}
// remove and return a random item
public Item dequeue() {
if (isEmpty()) throw new NoSuchElementException("the deque is empty.");
Node<Item> temp = head.next;
int r = StdRandom.uniform(0, n);
for (int i = 0; i < r; i++) {
temp = temp.next;
}
Item randomItem = temp.item;
Node<Item> preTemp = temp.prev;
Node<Item> nextTemp = temp.next;
preTemp.next = nextTemp;
nextTemp.prev = preTemp;
n--;
return randomItem;
}
// return a random item (but do not remove it)
public Item sample() {
if (isEmpty()) throw new NoSuchElementException("the deque is empty.");
Node<Item> temp = head.next;
for (int i = 0; i < StdRandom.uniform(0, n); i++) {
temp = temp.next;
}
return temp.item;
}
// return an independent iterator over items in random order
public Iterator<Item> iterator() {
return new LinkedIterator(this.head);
}
private class LinkedIterator implements Iterator<Item> {
private RandomizedQueue.Node<Item> current;
public LinkedIterator(RandomizedQueue.Node<Item> head) {
this.current = head.next;
RandomizedQueue.Node<Item> loopNode = current;
for (int i = 0; i < n; i++) {
int r = i + StdRandom.uniform(n - i);
swapItem(i, r, loopNode);
loopNode = current.next;
}
}
public boolean hasNext() {
return this.current != tail;
}
public void remove() {
throw new UnsupportedOperationException();
}
private void swapItem(int i, int random, RandomizedQueue.Node<Item> loopNode) {
RandomizedQueue.Node<Item> chosen = loopNode;
Item temp;
RandomizedQueue.Node<Item> chooser = loopNode;
for (int j = i; j <= n; j++) {
if (j == random) {
chosen = loopNode;
break;
}
loopNode = loopNode.next;
}
temp = chosen.item;
chosen.item = chooser.item;
chooser.item = temp;
}
public Item next() {
if (!this.hasNext()) {
throw new NoSuchElementException();
} else {
Item item = this.current.item;
this.current = this.current.next;
return item;
}
}
}
// unit testing (required)
public static void main(String[] args) {
int k = Integer.parseInt(args[0]);
RandomizedQueue<String> test = new RandomizedQueue<>();
for (int i = 0; i < k; i++) {
test.enqueue(StdIn.readString());
}
int n = k + 1;
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (StdRandom.uniform(n) < k) {
test.dequeue();
test.enqueue(item);
}
}
for (String s : test
) {
System.out.print(s + " ");
}
System.out.println();
for (String s : test
) {
System.out.print(s + " ");
}
}
}
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdRandom;
public class Permutation {
public static void main(String[] args) {
int k = Integer.parseInt(args[0]);
RandomizedQueue<String> test = new RandomizedQueue<>();
for (int i = 0; i < k; i++) {
test.enqueue(StdIn.readString());
}
int n = k+1;
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (StdRandom.uniform(n) < k) {
test.dequeue();
test.enqueue(item);
}
}
for (String s : test
) {
System.out.println(s);
}
}
}