游戏Algorithm----洗牌算法----探讨

洗牌,现理解就是讲一个数组打算顺序。
        我想了两种方法。
        第二种的思路是:如果数组长度为五,则在第一个到第四个随机一个数,与之交换。这样第五的元素就是装了一个随机数,然后再在第一个到第三个随机一个数,与数组第四个元素交换,以此类推。
        第一种思路是,套用collections的shuffle方法,代码比较简洁,其实是一样的,但是不比较大小,直接交换。想一下,不比较大小是对的。


   /** 
    * 打乱数组,洗牌方法①
    */
   public  void shuffle(int[] array) {
	   Random rnd = new Random();
       int size = array.length;
       // Shuffle array
       for (int i=size; i>1; i--){
    	   int index = rnd.nextInt(i);
    	   int temp = array[index];
    	   array[index] = array[i-1];
    	   array[i-1] = temp;
       }
   }
   /** 
    * 打乱数组,冒泡洗牌方法②
    */
   public  void bubbleShuffle(int[] arr) {
	   int len = arr.length;
	   for (int i = 0; i < len - 3; i++) {
		   int index  = (int)(Math.random()*(len - 2 - i));
		   if(arr[index]!=arr[len - 1 - i])
			   swap(arr,len - 1 - i,index);
		   }
	   swap(arr, 0, 1);
   }
   public void swap(int[] arr,int a, int b){
	   int t = arr[a];
	   arr[a] = arr[b];
	   arr[b] = t;
	   System.out.println("交换["+a+","+b+"]");
   }

品味一下Collections.shuffle()

    public static void shuffle(List<?> list) {
        if (r == null) {
            r = new Random();
        }
        shuffle(list, r);
    }
    private static Random r;
    public static void shuffle(List<?> list, Random rnd) {
        int size = list.size();
        if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
            for (int i=size; i>1; i--)
                swap(list, i-1, rnd.nextInt(i));
        } else {
            Object arr[] = list.toArray();

            // Shuffle array
            for (int i=size; i>1; i--)
                swap(arr, i-1, rnd.nextInt(i));

            // Dump array back into list
            ListIterator it = list.listIterator();
            for (int i=0; i<arr.length; i++) {
                it.next();
                it.set(arr[i]);
            }
        }
    }

    /**
     * Swaps the two specified elements in the specified array.
     */
    private static void swap(Object[] arr, int i, int j) {
        Object tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

回答一楼VSTUM的问题:

比如说,为什么collections的shuffle方法加入了对RandomAccess的判断?
对List特别的遍历算法中,要尽量判断是属于随机访问RandomAccess(如ArrayList)还是顺序访问SequenceAccess(如LinkedList),
对于实现了RandomAccess接口的类实例而言
     for (int i=0, i<list.size(); i++)
         list.get(i);
的运行速度要快于下面:
     for (Iterator i=list.iterator(); i.hasNext(); )
         i.next();


你可能感兴趣的:(java,Algorithm,游戏,算法)