import java.util.Random; /** * This class illustrates various algorithms for shuffling an array of integers * * @author alchambers * @version sp17 */ public class Shuffler{ // This variable was promoted to have class scope since // it is used in more than one method. Note, however, that // this is *not* an instance variable but a static variable private static Random rng; /** * Shuffles by swapping random elements in the array */ private static void shuffle1(int[] values){ final int NUM_TIMES = values.length; for(int i = 0; i < NUM_TIMES; i++){ int pos1 = rng.nextInt(values.length); int pos2 = rng.nextInt(values.length); int temp = values[pos2]; values[pos2] = values[pos1]; values[pos1] = temp; } } /** * Repeatedly removes and then re-inserts the first * element in the array */ private static void shuffle2(int[] values){ for(int i = 0; i < values.length; i++){ int firstElement = values[0]; int newPos = rng.nextInt(values.length); // Shift all elements in the range [0...newPos] left by one spot for(int j = 0; j < newPos; j++){ values[j] = values[j+1]; } // Insert the previously first element into the // hole we made in the array values[newPos] = firstElement; } } /** * Splits array into two halves. Then interleaves the values * from these two halves back into the array. */ private static void shuffle3(int[] values){ int length1 = values.length / 2; int length2 = values.length - length1; int[] firstHalf = new int[length1]; int[] secondHalf = new int[length2]; final int NUM_TIMES = values.length; for(int i = 0; i < NUM_TIMES; i++){ // Split the array into two halves for(int j = 0; j < values.length; j++){ if(j < length1){ firstHalf[j] = values[j]; } else{ secondHalf[j-length1] = values[j]; } } // Interleave the two halves. Note that firstHalf.length is always // less than or equal to secondHalf.length int j, curr = 0; for(j = 0; j < firstHalf.length; j++){ values[curr] = firstHalf[j]; curr++; values[curr] = secondHalf[j]; curr++; } // Check if there is a remaining value in secondHalf that needs to be copied over if(curr == values.length-1){ values[curr] = secondHalf[j]; } } } /** * Assigns each element to a brand new randomly chosen spot in the array */ private static void shuffle4(int[] values){ int[] newValues = new int[values.length]; boolean[] taken = new boolean[values.length]; // starts out as all false for(int i = 0; i < values.length; i++){ int element = values[i]; // Find a new random spot for this element in the array // May need to generate more than one spot until we find // one that hasn't been taken yet int newPos = -1; do{ newPos = rng.nextInt(newValues.length); }while(taken[newPos]); // Store the element in its new spot and mark this // spot as taken taken[newPos] = true; newValues[newPos] = element; } // Need to copy over the new array to the old array! for(int i = 0; i < values.length; i++){ values[i] = newValues[i]; } } /** * Prints an array to the screen */ private static void printArray(int[] values){ for(int i = 0; i < values.length; i++){ System.out.print(values[i] + " "); } System.out.println(); } public static void main(String[] args){ rng = new Random(); int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // Call various shuffling algorithms below printArray(array); shuffle4(array); printArray(array); } }