算法-第四版-练习1.3.35解答

题目

随机队列。随机队列能够存储一族元素并支持表1.3.11中的API:

表 1.3.11 泛型随机队列的API
public class RandomQueue<Item>  
RandomQueue() 创建一条空的随机队列
boolean isEmpty() 队列是否为空
void enqueue(Item item) 添加一个元素
Item dequeue() 删除并随机返回一个元素(取样且不放回)
Item sample() 随机返回一个元素但不删除它(取样且放回)
   

编写一个RandoQueue类来实现这份API。提示:使用(能够动态调整大小的)数组表示数据。删除一个元素时,随机交换某个元素(索引在0和N-1之间)和末尾元素(索引为N-1)的位置,然后像ResizingArrarStack一样删除并返回末位元素。编写一个用例,使用RandomQueue<Card>在桥牌中发牌(每人13张)。

思路

随机取一个0到N-1之间的值来模拟发牌,并把末尾元素补充到抽出的位置。

代码

package Chap1.$3;

import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdRandom;

import java.util.Iterator;

public class E35<Item> implements Iterable<Item>
{
    private static int N = 0;
    private Item[] a = (Item[]) new Object[1];
    public boolean isEmpty()
    {
        return N == 0;
    }
    public int size()
    {
        return N;
    }
    public void resize(int max)
    {
        Item[] temp = (Item[]) new Object[max];
        int j = 0;
        for (int i = 0; i < N; i++)
            temp[j++] = a[i];
        a = temp;
    }
    public void enqueue(Item item)
    {
        if (N == a.length) resize(a.length * 2);
        a[N++] = item;
    }
    public Item dequeue()
    {
        int n = StdRandom.uniform(N);
        Item temp = a[n];
        a[n] = a[--N];
        if (N == a.length / 4) resize(a.length / 2);
        return temp;
    }
    public Item sample()
    {
        int n = StdRandom.uniform(N);
        return a[n];
    }

    public static void main(String[] args)
    {
        E35<Integer> e = new E35<Integer>();
        for (int i = 1; i < 14; i++)
        {
            e.enqueue(i);
        }
        int maxsize = e.size();

        Iterator<Integer> iterator = e.iterator();
        while (iterator.hasNext()) System.out.print(iterator.next() + " ");
        System.out.println();
        
        
        for (int i = 0; i < maxsize; i++)
            System.out.print(e.dequeue() + " ");
        
    }


    public Iterator<Item> iterator()
    {
        return new ArraryIterator();
    }
    public class ArraryIterator implements Iterator<Item>
    {
        private int i = N;
        public boolean hasNext()
        {
            return i > 0;
        }
        public Item next()
        {
            int n = StdRandom.uniform(i);
            Item temp = a[n];
            a[n] = a[--i];
            return temp;
        }
        public void remove()
        {

        }
    }
}

注意

解答中用Integer代替Card;main函数中一个迭代器输出,一个for循环输出,每次只能用一个,不然第一个会打乱数组,导致第二个输出错误。

猜你喜欢

转载自blog.csdn.net/qq_26207065/article/details/81479051