Princeton Alhorithms Deques and Randomized Queues

普林斯頓大學算法課第 2 次作業“雙端隊列與隨機隊列 ”。

這一次作業算是比較基本的作業,就是實現雙端隊列與隨機隊列,可以說是鞏固鏈表和數組的基本知識的好作業,而且,初步認識到了不可變類型,初步瞭解到了什麼是“多次調用不產生副作用”。

本次代碼獲得 95 分,正確性滿分,空間複雜度滿分(還有附加分),時間複雜度稍微扣了點分,但是也懶得去改了。

import java.util.Iterator;
import java.util.NoSuchElementException;
 
public class Deque<Item> implements Iterable<Item> {
 
    private Node<Item> head;
    private Node<Item> tail;
    private int size;
 
    // construct an empty deque
    public Deque() {
    }
 
    // 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<Item> node = new Node<>(item);
        node.setNext(head);
        if (isEmpty()) {
            tail = node;
        }
        head = node;
        size++;
    }
 
    // add the item to the back
    public void addLast(Item item) {
        if (size == 0) {
            addFirst(item);
        } else {
            if (item == null) {
                throw new IllegalArgumentException();
            }
            Node<Item> node = new Node<>(item);
            tail.setNext(node);
            tail = node;
            if (isEmpty()) {
                head = tail;
            }
            size++;
        }
    }
 
    // remove and return the item from the front
    public Item removeFirst() {
        if (isEmpty()) {
            throw new NoSuchElementException();
        }
        Item item = head.getItem();
        head = head.getNext();
        size--;
        if (isEmpty()) {
            tail = head;
        }
        return item;
    }
 
    // remove and return the item from the back
    public Item removeLast() {
        if (isEmpty()) {
            throw new NoSuchElementException();
        }
        if (size == 1) {
            return removeFirst();
        }
        Node<Item> cur = head;
        while (cur.getNext() != tail) {
            cur = cur.getNext();
        }
        Item item = tail.getItem();
        tail = cur;
        tail.setNext(null);
        size--;
        return item;
    }
 
    // return an iterator over items in order from front to back
    @Override
    public Iterator<Item> iterator() {
        return new Iterator<Item>() {
            private Node<Item> cur = head;
 
            @Override
            public boolean hasNext() {
                return cur != null;
            }
 
            @Override
            public Item next() {
                if (cur == null) {
                    throw new NoSuchElementException();
                }
                Item item = cur.getItem();
                cur = cur.getNext();
                return item;
            }
        };
    }
 
    // unit testing (required)
    public static void main(String[] args) {
        Deque<Integer> dq = new Deque<>();
        dq.addFirst(0);
        System.out.println(dq.removeFirst());
        dq.addFirst(1);
        System.out.println(dq.removeLast());
        dq.addLast(2);
        System.out.println(dq.removeFirst());
        dq.addLast(3);
        System.out.println(dq.removeLast());
        System.out.println(dq.isEmpty());
        dq.addFirst(200);
        dq.addFirst(100);
        dq.addLast(300);
        dq.addLast(400);
        System.out.println(dq.size());
        Iterator<Integer> it = dq.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }
 
}
 
class Node<Item> {
    private final Item item;
    private Node<Item> next;
 
    public Node(Item item) {
        this.item = item;
        next = null;
    }
 
    public void setNext(Node<Item> next) {
        this.next = next;
    }
 
    public Node<Item> getNext() {
        return next;
    }
 
    public Item getItem() {
        return item;
    }
}
import java.util.Iterator;
import java.util.NoSuchElementException;
 
import edu.princeton.cs.algs4.StdRandom;
 
public class RandomizedQueue<Item> implements Iterable<Item> {
 
    private Node<Item> head;
    private int size;
 
    // construct an empty randomized queue
    public RandomizedQueue() {
    }
 
    // is the randomized queue empty?
    public boolean isEmpty() {
        return size == 0;
    }
 
    // return the number of items on the randomized queue
    public int size() {
        return size;
    }
 
    // add the item
    public void enqueue(Item item) {
        if (item == null) {
            throw new IllegalArgumentException();
        }
        Node<Item> node = new Node<>(item);
        node.setNext(head);
        head = node;
        size++;
    }
 
    private Item randomize(boolean delete) {
        if (isEmpty()) {
            throw new NoSuchElementException();
        }
        int r = StdRandom.uniform(0, size);
        if (r == 0) {
            // remove head only
            Item item = head.getItem();
            if (delete) {
                head = head.getNext();
                size--;
            }
            return item;
        }
        // go through, and keep pre and cur
        Node<Item> pre = head;
        Node<Item> cur = head.getNext();
        for (int i = 1; i < r; i++) {
            pre = cur;
            cur = cur.getNext();
        }
        Item item = cur.getItem();
        if (delete) {
            pre.setNext(cur.getNext());
            size--;
        }
        return item;
    }
 
    // remove and return a random item
    public Item dequeue() {
        return randomize(true);
    }
 
    // return a random item (but do not remove it)
    public Item sample() {
        return randomize(false);
    }
 
    // return an independent iterator over items in random order
    @Override
    public Iterator<Item> iterator() {
        return new Iterator<Item>() {
 
            int left = size;
            boolean[] visited = new boolean[left];
 
            @Override
            public boolean hasNext() {
                return left > 0;
            }
 
            @Override
            public Item next() {
                if (left == 0) {
                    throw new NoSuchElementException();
                }
                int r = StdRandom.uniform(size);
                while (visited[r]) {
                    r = StdRandom.uniform(size);
                }
                visited[r] = true;
                left--;
                Node<Item> cur = head;
 
                for (int i = 0; i < r; i++) {
                    cur = cur.getNext();
                }
                return cur.getItem();
            }
        };
    }
 
    // unit testing (required)
    public static void main(String[] args) {
        RandomizedQueue<Integer> rq = new RandomizedQueue<>();
        rq.enqueue(1);
        rq.enqueue(2);
        rq.enqueue(3);
        System.out.println(rq.isEmpty());
        System.out.println(rq.size());
        System.out.println(rq.sample());
        System.out.println(rq.dequeue());
        Iterator<Integer> it = rq.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }
 
}
 
class Node<Item> {
    private final Item item;
    private Node<Item> next;
 
    public Node(Item item) {
        this.item = item;
        next = null;
    }
 
    public void setNext(Node<Item> next) {
        this.next = next;
    }
 
    public Node<Item> getNext() {
        return next;
    }
 
    public Item getItem() {
        return item;
    }
}

import edu.princeton.cs.algs4.StdIn;
 
import java.util.NoSuchElementException;
 
public class Permutation {
    public static void main(String[] args) {
        int k = Integer.parseInt(args[0]);
        RandomizedQueue<String> rq = new RandomizedQueue<>();
        while (!StdIn.isEmpty()) {
            rq.enqueue(StdIn.readString());
        }
        for (int i = 0; i < k; i++) {
            System.out.println(rq.dequeue());
        }
    }
}

歡迎關注我的個人博客以閱讀更多優秀文章:凝神長老和他的朋友們(https://www.jxtxzzw.com)

也歡迎關注我的其他平臺:知乎( https://s.zzw.ink/zhihu )、知乎專欄( https://s.zzw.ink/zhuanlan )、嗶哩嗶哩( https://s.zzw.ink/blbl )、微信公衆號( 凝神長老和他的朋友們 )
凝神長老的二維碼們

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章