Skip to content

Latest commit

 

History

History
640 lines (277 loc) · 9.3 KB

Queues.md

File metadata and controls

640 lines (277 loc) · 9.3 KB

queue

logo_2

  • 100/100

100/100

核心就是操作链表。

好像没啥大问题,轻轻松松。

Deque.java:

import edu.princeton.cs.algs4.StdOut;

  

import java.util.Iterator;

import java.util.NoSuchElementException;

  

public class Deque<Item> implements Iterable<Item> { // object overhead 16 Byte

    // at most 48n + 192 bytes of memory

    private int size; // 4 Byte

  

    private Node first; // 8 Byte ref

    private Node last; // 8 Byte ref

  
  

    private class Node{ // 16 Byte overhead

        Item item; // 8 Byte ref

        Node pre; // 8 Byte ref

        Node next; // 8 Byte ref

    }

  
  

    // construct an empty deque

    public Deque(){

        size = 0;

        first = null;

        last = null;

    }

  
  

    // is the deque empty?

    public boolean isEmpty() {

        return size == 0;

    }

  

    // return the number of items on the deque

    public int size(){return size;}

  

    // add the item to the front

    public void addFirst(Item item){

        if(item==null){

            throw new IllegalArgumentException();

        }

        Node oldFirst = first;

        first = new Node();

        first.item = item;

        first.next = oldFirst;

        first.pre = null;

  

        if(isEmpty()){

            last = first;

        }else{

            oldFirst.pre = first;

        }

        size++;

    }

  
  

    // add the item to the back

    public void addLast(Item item){

        if(item==null){

            throw new IllegalArgumentException();

        }

        Node oldLast = last;

        last = new Node();

        last.item = item;

        last.pre = oldLast;

        last.next = null;

  

        if(isEmpty()){

            first = last;

        }else{

            oldLast.next = last;

        }

        size++;

    }

  
  

    // remove and return the item from the front

    public Item removeFirst(){

        if(isEmpty()){

            throw new NoSuchElementException();

        }

        Item item = first.item;

        first = first.next;

        size--; // must decrease first

  

        if(isEmpty()){

            last = null;

        }else{

            first.pre = null;

        }

        return item;

    }

  
  

    // remove and return the item from the back

    public Item removeLast(){

        if(isEmpty()){

            throw new NoSuchElementException();

        }

        Item item = last.item;

        last = last.pre;

        size--;

  

        if(isEmpty()){

            first = null;

        }else{

            last.next = null;

        }

        return item;

    }

  
  

    // return an iterator over items in order from front to back

    public Iterator<Item> iterator(){

        return new DequeIterator();

    }

  

    private class DequeIterator implements Iterator<Item> {

        private Node current = first;

  

        public boolean hasNext() {

            return current != null;

        }

  

        public Item next() {

            if(!hasNext()){

                throw new NoSuchElementException();

            }

            Item item = current.item;

            current = current.next;

            return item;

        }

  

        public void remove() {

            /* not supported */

            throw new UnsupportedOperationException();

        }

    }

  
  

    // unit testing (required)

    public static void main(String[] args){

        Deque<Integer> dq = new Deque<Integer>();

        for(int i=0;i<5;i++){

            dq.addFirst(i);

        }

        for(int i=5;i<10;i++){

            dq.addLast(i);

        }

        StdOut.println(dq.size());

        StdOut.println(dq.removeFirst());

        StdOut.println(dq.size());

        StdOut.println(dq.removeLast());

        StdOut.println(dq.size());

        Iterator<Integer> it = dq.iterator();

        while(it.hasNext()){

            StdOut.println(it.next());

        }

    }

}

RandomizedQueue.java:

import edu.princeton.cs.algs4.StdOut;

import edu.princeton.cs.algs4.StdRandom;

  

import java.util.Iterator;

import java.util.NoSuchElementException;

  

public class RandomizedQueue<Item> implements Iterable<Item> {

  

    private Item[] randomizedQueue;

    private int n;

  

    // construct an empty randomized queue

    public RandomizedQueue(){

        n = 0;

        randomizedQueue = (Item[]) new Object[1];

    }

  

    private void resize(int newSize){

//        if(newSize <= 0){

//            throw new IllegalArgumentException();

//        }

        Item[] copy = (Item[]) new Object[newSize];

        for(int i = 0; i < n; i++){

            copy[i] = randomizedQueue[i];

        }

        randomizedQueue = copy;

    }

    // 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();

        }

        if(n == randomizedQueue.length){

            // grow array: twice the size

            resize(2 * randomizedQueue.length);

        }

        randomizedQueue[n++] = item;

    }

  

    // remove and return a random item

    public Item dequeue(){

        if(isEmpty()){

            throw new NoSuchElementException();

        }

        // random

        int randNum = StdRandom.uniformInt(n); // [0,n)

        Item item = randomizedQueue[randNum];

  

        // 每次出队列都是等概率(uniformly random)

        // 就不需要线性移动randNum之后的所有元素

        if(randNum != n - 1){

            randomizedQueue[randNum] = randomizedQueue[n - 1];

        }

        randomizedQueue[n - 1] = null;

        n--;

  

        if(n > 0 && n == randomizedQueue.length / 4){

            resize(randomizedQueue.length / 2);

        }

  

        return item;

    }

  

    // return a random item (but do not remove it)

    public Item sample(){

        if(isEmpty()){

            throw new NoSuchElementException();

        }

        return randomizedQueue[StdRandom.uniformInt(n)];

    }

  

    // return an independent iterator over items in random order

    public Iterator<Item> iterator(){

        return new RandomizedQueueIterator();

    }

  

    private class RandomizedQueueIterator implements Iterator<Item> {

        private int index;

        private Item[] items;

  

        public RandomizedQueueIterator(){

            index = 0;

            items = (Item[]) new Object[n];

            for(int i=0;i<n;i++){

                items[i] = randomizedQueue[i];

            }

            StdRandom.shuffle(items); // in random order

        }

  

        public boolean hasNext() {

            return index < n;

        }

  

        public Item next() {

            if(!hasNext()){

                throw new NoSuchElementException();

            }

            return items[index++];

        }

  

        public void remove() {

            throw new UnsupportedOperationException();

        }

    }

  

    // unit testing (required)

    public static void main(String[] args){

        RandomizedQueue<Integer> rq = new RandomizedQueue<Integer>();

        StdOut.println(rq.size());

        for(int i=0 ;i < 10; i++){

            rq.enqueue(i);

        }

        StdOut.println(rq.size());

        StdOut.println(rq.dequeue());

        StdOut.println("new size: " + rq.size());

        StdOut.println(rq.sample());

        Iterator<Integer> it = rq.iterator();

        while(it.hasNext()){

            StdOut.println(it.next());

        }

    }

}

Permutation.java:

import edu.princeton.cs.algs4.StdIn;

import edu.princeton.cs.algs4.StdOut;

  

public class Permutation {

    public static void main(String[] args) {

        int k = Integer.parseInt(args[0]);

        RandomizedQueue<String> rq = new RandomizedQueue<String>();

  

        // input n strings, where n is not given

        String item;

        while (!StdIn.isEmpty()) {

            item = StdIn.readString();

            rq.enqueue(item);

        }

  

        // iterators have StdRandom.shuffle()

        for (String s : rq) {

            if (k == 0) {

                break;

            }

            StdOut.println(s);

            k--;

        }

    }

}