• 随机队列


    public class RandomQueue< Item >
    随机队列能够存储一组元素并支持如下API
    RandomQueue() 创建一个空队列
    isEmpty()判断队列是否为空
    enqueue(Item item) 添加一个元素
    dequeue()删除并返回一个随机元素
    sample() 随机返回一个元素,不删除

    方法

    1.使用动态数组存储数据
    2.删除元素时,随机交换某个元素和末尾元素的位置,然后删除并返回末尾元素
    3.编写随机迭代器,随机返回队列中的所有元素

    代码

    import edu.princeton.cs.algs4.StdRandom;
    import java.util.Iterator;
    import java.util.Random;
    
    /**
     * @author 鯉伴MAY
     * @param <Item>
     */
    public class RandomQueue<Item> implements Iterable<Item>{
        private Item[] array;
        private int N;
    
    
        private void resize(int max){
            Item[] temp = (Item[]) new Object[max];
            for (int i = 0; i < N; i++) {
                temp[i] = array[i];
            }
            array = temp;
        }
    
        public RandomQueue() {
            array = (Item[]) new Object[1];
            N = 0;
        }
        public boolean isEmpty() {
            return N==0;
        }
    
        public void enqueue(Item item){
            if(N == array.length) {
                resize(2*N);
            }
            array[N++] = item;
        }
    
        //随机返回一个元素 并删除
        public Item dequeue() {
            if(N==0){
                System.out.println("队列已空");
                return null;
            }
            Random random = new Random();
            int index = random.nextInt(N);//返回0到N-1之间的一个随机整数
            //交换array[N-1]和array[index]的值
            Item temp = array[N-1];
            array[N-1] = array[index];
            array[index] = temp;
            temp = array[--N];
            array[N] = null;//置空,避免对象游离
            if(N>0 && N == array.length/4)
                resize(array.length/2);
            return temp;
        }
    
        //随机返回一个元素但是不删除
        public Item sample() {
            if(N==0){
                System.out.println("队列已空");
                return null;
            }
            Random random = new Random();
            int index = random.nextInt(N);//返回0到N-1之间的一个随机整数
            return array[index];
        }
    
        @Override
        public Iterator<Item> iterator() {
            return new  RandomQueueIterator();
        }
    
        private class RandomQueueIterator implements Iterator {
    
            //使用一个数组记录打乱的下标,以打乱的下标去访问原数组,实现快速随机访问
            private int[] seq = new int[N];
            private int index = 0;
            public RandomQueueIterator() {
                for(int i=0;i<N;i++) {
                    seq[i] =i;
                }
                StdRandom.shuffle(seq);
                /*
                此函数的源码如下:
                public static void shuffle(int[] a) {
                    validateNotNull(a);
                    int n = a.length;
                    //此函数遍历数组,使每一个元素都随机和另一个交换为位置
                    //此方法何以保证每个新的迭代器得到N!种排列出现的可能性相等
                    for (int i = 0; i < n; i++) {
                        int r = i + uniform(n-i);     // between i and n-1
                        int temp = a[i];
                        a[i] = a[r];
                        a[r] = temp;
                    }
                }
                //返回0-n之间的随机一个正整数
                public static int uniform(int n) {
                    if (n <= 0) throw new IllegalArgumentException("argument must be positive: " + n);
                    return random.nextInt(n);
                }
                 */
            }
            @Override
            public boolean hasNext() {
                return index<N;
            }
    
            @Override
            public Object next() {
                return array[seq[index++]];
            }
        }
    }
    
    
  • 相关阅读:
    彻底理解jdbc为什么用反射创建驱动程序对象
    java反射
    hashcode(),equal()方法深入解析
    面试经验总结
    Spring安全权限管理(Spring Security)
    http认证方式
    ubuntu/linux mint 创建proc文件的三种方法(两)
    cocos2dx使用tolua关于字符串处理的一个问题
    Ubuntu——grub rescue 主引导修复
    BCM wifi分析
  • 原文地址:https://www.cnblogs.com/dwwzone/p/12859251.html
Copyright © 2020-2023  润新知