Skip to content
This repository was archived by the owner on Sep 6, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 174 additions & 0 deletions Algorithms, Part I/Week 2/Deques and Randomized Queues/Deque.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import edu.princeton.cs.algs4.StdOut;

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

/**
* Dequeue. 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.
* @param <Item> the type of elements in data structure
*/
public class Deque<Item> implements Iterable<Item> {
private Node first;
private Node last;
private int size;

/**
* Construct an empty deque.
*/
public Deque() {
}

/**
* Returns <tt>true</tt> if this deque contains no elements.
* @return <tt>true</tt> if this deque contains no elements.
*/
public boolean isEmpty() {
return first == null;
}

/**
* Returns the number of elements in this deque.
* @return the number of elements in this deque.
*/
public int size() {
return size;
}

/**
* Inserts the specified element at the beginning of this deque.
* @param item the element to add.
* @throws IllegalArgumentException if argument is null.
*/
public void addFirst(Item item) {
if (item == null) throw new IllegalArgumentException("Null value");

Node node = new Node();
node.item = item;
size++;

if (isEmpty()) {
first = node;
last = node;
return;
}

node.next = first;
first.prev = node;
first = node;
}

/**
* Appends the specified element to the end of this deque.
* @param item the element to add.
* @throws IllegalArgumentException if argument is null.
*/
public void addLast(Item item) {
if (item == null) throw new IllegalArgumentException("Null value");

Node node = new Node();
node.item = item;
size++;

if (isEmpty()) {
first = node;
last = node;
return;
}

node.prev = last;
last.next = node;
last = node;
}

/**
* Returns the first element in this deque.
* @return the first element in this deque.
* @throws NoSuchElementException if this deque is empty.
*/
public Item removeFirst() {
if (isEmpty()) throw new NoSuchElementException("Deque is empty!");

Node temp = first;
size--;

if (temp.next == null) {
first = null;
last = null;
return temp.item;
}

first = temp.next;
first.prev = null;
temp.next = null;

return temp.item;
}

/**
* Returns the last element in this deque.
* @return the last element in this deque.
* @throws NoSuchElementException if this deque is empty.
*/
public Item removeLast() {
if (isEmpty()) throw new NoSuchElementException("Deque is empty!");

Node temp = last;
size--;

if (temp.prev == null) {
first = null;
last = null;
return temp.item;
}

last = temp.prev;
last.next = null;
temp.prev = null;

return temp.item;
}

/**
* Returns an iterator over items in order from front to back.
* @return an iterator over items in order from front to back.
*/
public Iterator<Item> iterator() {
return new Iterator<Item>() {
private Node head = first;

public boolean hasNext() {
return head != null;
}

public Item next() {
if (!hasNext()) throw new NoSuchElementException("Iteration has no more elements!");
Node temp = head;
head = temp.next;
return temp.item;
}
};
}

/**
* Auxiliary class that represents Node with two links.
*/
private class Node {
private Item item;
private Node next;
private Node prev;
}

public static void main(String[] args) {
Deque<String> deque = new Deque<>();
deque.addFirst("First");
deque.addFirst("Second");
deque.addFirst("Third");
deque.addFirst("Fourth");
for (String s : deque) {
StdOut.println(s);
}
StdOut.println(deque.removeLast());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

/**
* Takes an integer k as a command-line argument; reads 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.
*/
public class Permutation {
public static void main(String[] args) {
RandomizedQueue<String> queue = new RandomizedQueue<>();
int n = Integer.parseInt(args[0]);

while (!StdIn.isEmpty()) {
queue.enqueue(StdIn.readString());
}

for (int i = 0; i < n; i++) {
StdOut.println(queue.dequeue());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;

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

/**
* A randomized <code>RandomizedQueue</code> is similar to a stack or
* <code>RandomizedQueue</code>, except that the item removed is chosen uniformly at random among
* items in data structure.
* @param <Item> the type of elements in data structure.
*/
public class RandomizedQueue<Item> implements Iterable<Item> {
private Item[] data;
private int head;

/**
* Construct an empty randomized <code>RandomizedQueue</code>.
*/
public RandomizedQueue() {
data = (Item[]) new Object[1];
}

/**
* Returns <tt>true</tt> if this <code>RandomizedQueue</code> contains no elements.
* @return <tt>true</tt> if this <code>RandomizedQueue</code> contains no elements.
*/
public boolean isEmpty() {
return head == 0;
}

/**
* Returns the number of elements in this <code>RandomizedQueue</code>.
* @return the number of elements in this <code>RandomizedQueue</code>.
*/
public int size() {
return head;
}

/**
* Add item at first position.
* @param item the element to add.
* @throws IllegalArgumentException if argument is null.
*/
public void enqueue(Item item) {
if (item == null) throw new IllegalArgumentException("Argument is null!");
if (head == data.length) resize(data.length * 2);
data[head] = item;
head++;
}

/**
* Remove and return a random item.
* @return random item from <code>RandomizedQueue</code>.
* @throws NoSuchElementException if <code>RandomizedQueue</code> is empty.
*/
public Item dequeue() {
if (isEmpty()) throw new NoSuchElementException("RandomizedQueue is empty!");
if (head > 0 && head == data.length / 4) resize(data.length / 2);

int random = StdRandom.uniform(head);
Item item = data[random];
head--;

if (random == head) {
data[random] = null;
return item;
}

data[random] = data[head];
data[head] = null;
return item;
}

/**
* Return a random item, but without removing it.
* @return random item from <code>RandomizedQueue</code>.
* @throws NoSuchElementException if <code>RandomizedQueue</code> is empty.
*/
public Item sample() {
if (isEmpty()) throw new NoSuchElementException("RandomizedQueue is empty!");
return data[StdRandom.uniform(head)];
}

/**
* Returns an independent iterator over items in random order (With modern version of
* Fisher–Yates shuffle).
* @return an independent iterator over items in random order.
*/
public Iterator<Item> iterator() {
return new Iterator<Item>() {
private Item[] shuffledData;
private int n = head;

{
shuffledData = (Item[]) new Object[data.length];
for (int i = 0; i < head; i++) {
shuffledData[i] = data[i];
}
}

public boolean hasNext() {
return n > 0;
}

public Item next() {
if (!hasNext()) throw new NoSuchElementException("Iteration has no more elements!");

if (n == 1) {
n = 0;
return shuffledData[0];
}

int random = StdRandom.uniform(n);
Item result = shuffledData[random];
n--;

if (random == n)
return result;

shuffledData[random] = shuffledData[n];
return result;
}
};
}

private void resize(int capacity) {
Item[] newArray = (Item[]) new Object[capacity];

for (int i = 0; i < head; i++) {
newArray[i] = data[i];
}

data = newArray;
}

public static void main(String[] args) {
RandomizedQueue<String> queue = new RandomizedQueue<>();
queue.enqueue("First");
queue.enqueue("Second");
queue.enqueue("Third");
queue.enqueue("Forth");
queue.enqueue("Fifth");

StdOut.println("Sample");
StdOut.println(queue.sample());
StdOut.println(queue.sample());
StdOut.println(queue.sample());
StdOut.println(queue.sample());
StdOut.println(queue.sample());
StdOut.println();

StdOut.println("For each");
for (String s : queue) {
StdOut.println(s);
}

queue.dequeue();
queue.dequeue();
queue.dequeue();
queue.dequeue();
queue.dequeue();
}
}