您的位置:首页 > 编程语言 > Go语言

Coursare·Algorithms, Part I第二周作业

2018-02-08 17:30 1316 查看
本周作业是相比较第一周要简单一些,主要写一个双端队列(Deque)和一个随机队列(Randomized Queue)以及一个客户端(Permutation)

Deque

要求:

A double-ended queue or deque (pronounced “deck”) is a generalization of a stack and a queue that supports adding and removing items from either the front or the back of the data structure. Create a generic data type Deque that implements the following API:



异常:

Throw a java.lang.IllegalArgumentException if the client calls either

addFirst() or addLast() with a null argument.

Throw a java.util.NoSuchElementException if the client calls either

removeFirst() or removeLast when the deque is empty.

Throw a java.util.NoSuchElementException if the client calls the

next() method in the iterator when there are no more items to return.

Throw a java.lang.UnsupportedOperationException if the client calls

the remove() method in the iterator.

性能:

Your deque implementation must support each deque operation (including construction) in constant worst-case time. A deque containing n items must use at most 48n + 192 bytes of memory and use space proportional to the number of items currently in the deque. Additionally, your iterator implementation must support each operation (including construction) in constant worst-case time.

内容:

写一个双端链表,至少包含上面api给出的方法,在最恶劣的情况下,n个数据时最多使用 48n+192 个字节,因为可以在队头插入和删除数据,所以我选择用链表构成

import java.util.Iterator;
import java.util.NoSuchElementException;

public class Deque<Item> implements Iterable<Item> {
private Node first;
private Node last;
private int size;

private class Node {
Item node;
Node next;  // 下一节点
Node pre;       // 上一节点
}

public Deque() {
first = null;
last = null;
size = 0;
}

public boolean isEmpty() {
return size == 0;
}

public void addFirst(Item item) {
if (item == null) {
throw new IllegalArgumentException();
}
// 将数据插入头部
Node oldNode = first;
first = new Node();
first.node = item;
first.next = oldNode;
// 判断是否为空,为空的话尾节点指向头结点数据,不为空将原头节点的上一节点指向新建头结点
if (isEmpty()) {
last = first;
} else {
oldNode.pre = first;
}
// 数量+1
size++;
}

public void addLast(Item item) {
if (item == null) {
throw new IllegalArgumentException();
}
Node oldNode = last;
last = new Node();
last.node = item;
last.pre = oldNode;
if (isEmpty()) {
first = last;
} else {
oldNode.next = last;
}
size++;
}

public Item removeFirst() {
Node oldNode = first;
if (isEmpty()) {
throw new NoSuchElementException();
} else if (first != last) {
// 当头结点和尾节点不是同一节点时,将下一个头结点的上一节点设置为null
first.next.pre = null;
}
first = first.next;
size--;
return oldNode.node;
}

public Item removeLast() {
Node oldNode = last;
if (isEmpty()) {
throw new NoSuchElementException();
} else if (first != last) {
// 当头结点和尾节点不是同一节点时,将下一个尾结点的下一节点设置为null
last.pre.next = null;
}
last = last.pre;
size--;
return oldNode.node;
}

public int size() {
return size;
}

@Override
public Iterator<Item> iterator() {
return new MyIterator();
}

private class MyIterator implements Iterator<Item> {
private Node current = first;

@Override
public boolean hasNext() {
return current != null;
}

@Override
public Item next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
Node oldNode = current;
current = current.next;
return oldNode.node;
}

@Override
public void remove() {
throw new UnsupportedOperationException();
}
}

public static void main(String[] args) {
Deque<Integer> deque = new Deque<Integer>();
deque.addLast(1);

cfa7
System.out.println(deque.removeFirst());
deque.addFirst(3);
System.out.println(deque.removeLast());
}
}


Randomized Queue

要求:

A randomized queue is similar to a stack or queue, except that the item removed is chosen uniformly at random from items in the data structure. Create a generic data type RandomizedQueue that implements the following API:



异常:

Throw a java.lang.IllegalArgumentException if the client calls enqueue() with a null argument.

Throw a java.util.NoSuchElementException if the client calls either sample() or dequeue() when the randomized queue is empty.

Throw a java.util.NoSuchElementException if the client calls the next() method in the iterator when there are no more items to return.

Throw a java.lang.UnsupportedOperationException if the client calls the remove() method in the iterator.

性能:

Your randomized queue implementation must support each randomized queue operation (besides creating an iterator) in constant amortized time. That is, any sequence of m randomized queue operations (starting from an empty queue) must take at most cm steps in the worst case, for some constant c. A randomized queue containing n items must use at most 48n + 192 bytes of memory. Additionally, your iterator implementation must support operations next() and hasNext() in constant worst-case time; and construction in linear time; you may (and will need to) use a linear amount of extra memory per iterator.

内容:

写一个随机队列,至少包含上面api给出的方法,在最恶劣的情况下,n个数据时最多使用 48n+192 个字节,每个iterator实例的遍历顺序是相对独立的,而且是在线性时间内,基于此我选择用数组来实现

import java.util.Iterator;
import java.util.NoSuchElementException;

import edu.princeton.cs.algs4.StdRandom;

public class RandomizedQueue<Item> implements Iterable<Item> {
private Item[] item;
private int size;

public RandomizedQueue() {
item = (Item[]) new Object[8];
size = 0;
}

public boolean isEmpty() {
return size == 0;
}

public int size() {
return size;
}

public void enqueue(Item item) {
if (size >= this.item.length) {
resize(this.item.length * 2);
}

if (item == null) {
throw new IllegalArgumentException();
}
this.item[size++] = item;
}

public Item dequeue() {
if (isEmpty()) {
throw new NoSuchElementException();
}
int n = StdRandom.uniform(0, size);
Item tempItem = item
;
// 将数组n之后的数前移
for (int i = n; i < size - 1; i++) {
item[i] = item[i+1];
}
size--;
// 判断大小,并调整大小
if (size < item.length/4) {
resize(item.length/2);
}
return tempItem;
}

public Item sample() {
if (isEmpty()) {
throw new NoSuchElementException();
}
int n = StdRandom.uniform(0, size);
return item
;
}

private void resize(int capacity) {
Item[] temp = (Item[]) new Object[capacity];
for (int i = 0; i < size; i++) {
temp[i] = item[i];
}
item = temp;
}

@Override
public Iterator<Item> iterator() {
return new MyIterator();
}

private class MyIterator implements Iterator<Item> {
private final int[] n = StdRandom.permutation(size);
private int current = 0;

@Override
public boolean hasNext() {
return current != n.length;
}

@Override
public Item next() {
if (!hasNext()) {
throw new NoSuchElementException();
}

return item[n[current++]];
}

@Override
public void remove() {
throw new UnsupportedOperationException();
}

}

public static void main(String[] args) {
RandomizedQueue<String> rq = new RandomizedQueue<String>();

for (int i = 0; i < 10; i++) {
rq.enqueue("第" + i + "个");
}
for (int i = 0; i < 10; i++) {
System.out.println(rq.sample());
}
System.out.println("----------------------------------------");
Iterator<String> iter = rq.iterator();
while (iter.hasNext()) {
System.out.println(iter.next());
}
System.out.println("----------------------------------------");
Iterator<String> iter1 = rq.iterator();
while (iter1.hasNext()) {
System.out.println(iter1.next());
}
System.out.println("----------------------------------------");
System.out.println(rq.dequeue());
}
}


Permutation

要求:

Write a client program Permutation.java that takes an integer k as a command-line argument; reads in a sequence of strings from standard input using StdIn.readString(); and prints exactly k of them, uniformly at random. Print each item from the sequence at most once.

性能:

The running time of Permutation must be linear in the size of the input. You may use only a constant amount of memory plus either one Deque or RandomizedQueue object of maximum size at most n. (For an extra challenge, use only one Deque or RandomizedQueue object of maximum size at most k.)

分析:

因为需要随机输出打印存入的数据,所以用RandomizedQueue比较好,这里有一个挑战,是让选用的数据结构最大值是输入的k,这里我没有完成,后续如果有什么想法会及时更新

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class Permutation {
public static void main(String[] args) {
// 调用函数传入的值k
int k = Integer.parseInt(args[0]);

RandomizedQueue<String> rq = new RandomizedQueue<String>();
while (!StdIn.isEmpty()) {
rq.enqueue(StdIn.readString());
}
for (int i = 0; i < k; i++) {
StdOut.println(rq.dequeue());
}
}
}


欢迎大家评论探讨哦
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Algorithms Coursare