zoukankan      html  css  js  c++  java
  • AlgorithmsI PA2: Randomized Queues and Deques RandomizedQueue

    RandomizedQueue 有几个关键点:

    1. 选择合适的数据结构,因为需要任意位置删除元素,Linked list 做不到,必须使用resizing arrays.

    2. resizing 的技巧。

        Q. How to grow array?
        A. If array is full, create a new array of twice the size, and copy items. 

        Q. How to shrink array? 
        A: halve size of array when array is one-quarter full 
    3. 正确使用StdRandom.shuffle. 要能实现并行使用Iterator,洗牌不是洗array 本身,而是生成一个乱序的index. 

    Java code:
    //RandomizedQueue - should be implemented using resizing arrays
    import edu.princeton.cs.algs4.StdIn; 
    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[] q;         // array of items
        private int N;            // number of elements 
        
        // construct an empty randomized queue
        public RandomizedQueue()  {               
            q = (Item[]) new Object[1];
            N = 0;
        }
        
        // is the queue empty?
        public boolean isEmpty()  {               
             return N == 0;
        }
        
        // return the number of items on the queue
        public int size()  {                     
            return N;
        }
        
        // resize the underlying array holding the elements
        private void resize(int capacity) {
            assert capacity >= N;
            Item[] temp = (Item[]) new Object[capacity];
            for (int i = 0; i < N; i++) {
                temp[i] = q[i];
            }
            q = temp;
        }
        
        // add the item
        //Throw a java.lang.NullPointerException if the client attempts to add a null item
        public void enqueue(Item item)  {     
            if(item == null) {
                throw new NullPointerException("add a null item");
            }
            if(N == q.length) {
                 resize(2 * q.length);   // double size of array if necessary
            }
            q[N++] = item;              // add item
        }
        
        /*when deleting random element you can just simply switch it with the last element in array 
         * and decrease the array size counter. So deletion will take constant time.
         *throw a java.util.NoSuchElementException if the client attempts to sample or dequeue an item 
         *from an empty randomized queue;
        */
        // remove and return a random item
        public Item dequeue()  {                  
            if (isEmpty()) {
                throw new NoSuchElementException("No element");
            }
            int x = StdRandom.uniform(N);
            Item item = q[x];
            q[x] = q[--N];
            q[N] = null;
            
            if (N == q.length / 4 && N > 0) {
                resize(q.length / 2);
            }
            return item;
        }
        
        // return (but do not remove) a random item
        public Item sample()  {                  
            if(isEmpty()) {
                throw new NoSuchElementException("No element");
            }
             int x = StdRandom.uniform(N);
             return q[x];        
        }
        
        // return an independent iterator over items in random order
        public Iterator<Item> iterator()  {   
             return new ArrayIterator();
        }
        
        private class ArrayIterator implements Iterator<Item> {
             private int i;
             private int[] indexSequence;
             
             public ArrayIterator() {
                 i = 0;
                 indexSequence = new int[N];
                 for (int j = 0; j < N; j++) {
                     indexSequence[j] = j;
                 }
                 StdRandom.shuffle(indexSequence);
             }
        
             public boolean hasNext()  { 
                 return i < N ;      
             }
             public void remove() { 
                 throw new UnsupportedOperationException();  
             }
             
             public Item next() {
                 if (!hasNext()) { 
                     throw new NoSuchElementException();
                 }
                return q[indexSequence[i++]];
             }
        }
        
        public static void main(String[] args) {   // unit testing
        
        }
    }
  • 相关阅读:
    洛谷P6218 [USACO06NOV] Round Numbers S 题解 数位DP
    Duilib的双缓冲实现,附带GDI、WTL的双缓冲实现
    关于热键HotKey与WM_KEYDOWN的一点心得
    源码不匹配,找到了xxx的副本。
    SetForegroundWindow的失效问题: 跨进程的窗口前置。
    2021年4月的一份总结
    制作msi文件,exe转msi文件。
    内存限制
    ISPRS Vaihingen 数据集解析
    Linux中sudo、su和su -命令的区别小结
  • 原文地址:https://www.cnblogs.com/anne-vista/p/4843187.html
Copyright © 2011-2022 走看看