Related
I need to randomly shuffle the following Array:
int[] solutionArray = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1};
Is there any function to do that?
Using Collections to shuffle an array of primitive types is a bit of an overkill...
It is simple enough to implement the function yourself, using for example the Fisher–Yates shuffle:
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
class Test
{
public static void main(String args[])
{
int[] solutionArray = { 1, 2, 3, 4, 5, 6, 16, 15, 14, 13, 12, 11 };
shuffleArray(solutionArray);
for (int i = 0; i < solutionArray.length; i++)
{
System.out.print(solutionArray[i] + " ");
}
System.out.println();
}
// Implementing Fisher–Yates shuffle
static void shuffleArray(int[] ar)
{
// If running on Java 6 or older, use `new Random()` on RHS here
Random rnd = ThreadLocalRandom.current();
for (int i = ar.length - 1; i > 0; i--)
{
int index = rnd.nextInt(i + 1);
// Simple swap
int a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
}
}
Here is a simple way using an ArrayList:
List<Integer> solution = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
solution.add(i);
}
Collections.shuffle(solution);
Here is a working and efficient Fisher–Yates shuffle array function:
private static void shuffleArray(int[] array)
{
int index;
Random random = new Random();
for (int i = array.length - 1; i > 0; i--)
{
index = random.nextInt(i + 1);
if (index != i)
{
array[index] ^= array[i];
array[i] ^= array[index];
array[index] ^= array[i];
}
}
}
or
private static void shuffleArray(int[] array)
{
int index, temp;
Random random = new Random();
for (int i = array.length - 1; i > 0; i--)
{
index = random.nextInt(i + 1);
temp = array[index];
array[index] = array[i];
array[i] = temp;
}
}
Collections class has an efficient method for shuffling, that can be copied, so as not to depend on it:
/**
* Usage:
* int[] array = {1, 2, 3};
* Util.shuffle(array);
*/
public class Util {
private static Random random;
/**
* Code from method java.util.Collections.shuffle();
*/
public static void shuffle(int[] array) {
if (random == null) random = new Random();
int count = array.length;
for (int i = count; i > 1; i--) {
swap(array, i - 1, random.nextInt(i));
}
}
private static void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
Look at the Collections class, specifically shuffle(...).
You have a couple options here. A list is a bit different than an array when it comes to shuffling.
As you can see below, an array is faster than a list, and a primitive array is faster than an object array.
Sample Durations
List<Integer> Shuffle: 43133ns
Integer[] Shuffle: 31884ns
int[] Shuffle: 25377ns
Below, are three different implementations of a shuffle. You should only use Collections.shuffle if you are dealing with a collection. There is no need to wrap your array into a collection just to sort it. The methods below are very simple to implement.
ShuffleUtil Class
import java.lang.reflect.Array;
import java.util.*;
public class ShuffleUtil<T> {
private static final int[] EMPTY_INT_ARRAY = new int[0];
private static final int SHUFFLE_THRESHOLD = 5;
private static Random rand;
Main Method
public static void main(String[] args) {
List<Integer> list = null;
Integer[] arr = null;
int[] iarr = null;
long start = 0;
int cycles = 1000;
int n = 1000;
// Shuffle List<Integer>
start = System.nanoTime();
list = range(n);
for (int i = 0; i < cycles; i++) {
ShuffleUtil.shuffle(list);
}
System.out.printf("%22s: %dns%n", "List<Integer> Shuffle", (System.nanoTime() - start) / cycles);
// Shuffle Integer[]
start = System.nanoTime();
arr = toArray(list);
for (int i = 0; i < cycles; i++) {
ShuffleUtil.shuffle(arr);
}
System.out.printf("%22s: %dns%n", "Integer[] Shuffle", (System.nanoTime() - start) / cycles);
// Shuffle int[]
start = System.nanoTime();
iarr = toPrimitive(arr);
for (int i = 0; i < cycles; i++) {
ShuffleUtil.shuffle(iarr);
}
System.out.printf("%22s: %dns%n", "int[] Shuffle", (System.nanoTime() - start) / cycles);
}
Shuffling a Generic List
// ================================================================
// Shuffle List<T> (java.lang.Collections)
// ================================================================
#SuppressWarnings("unchecked")
public static <T> void shuffle(List<T> list) {
if (rand == null) {
rand = new Random();
}
int size = list.size();
if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
for (int i = size; i > 1; i--) {
swap(list, i - 1, rand.nextInt(i));
}
} else {
Object arr[] = list.toArray();
for (int i = size; i > 1; i--) {
swap(arr, i - 1, rand.nextInt(i));
}
ListIterator<T> it = list.listIterator();
int i = 0;
while (it.hasNext()) {
it.next();
it.set((T) arr[i++]);
}
}
}
public static <T> void swap(List<T> list, int i, int j) {
final List<T> l = list;
l.set(i, l.set(j, l.get(i)));
}
public static <T> List<T> shuffled(List<T> list) {
List<T> copy = copyList(list);
shuffle(copy);
return copy;
}
Shuffling a Generic Array
// ================================================================
// Shuffle T[]
// ================================================================
public static <T> void shuffle(T[] arr) {
if (rand == null) {
rand = new Random();
}
for (int i = arr.length - 1; i > 0; i--) {
swap(arr, i, rand.nextInt(i + 1));
}
}
public static <T> void swap(T[] arr, int i, int j) {
T tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static <T> T[] shuffled(T[] arr) {
T[] copy = Arrays.copyOf(arr, arr.length);
shuffle(copy);
return copy;
}
Shuffling a Primitive Array
// ================================================================
// Shuffle int[]
// ================================================================
public static <T> void shuffle(int[] arr) {
if (rand == null) {
rand = new Random();
}
for (int i = arr.length - 1; i > 0; i--) {
swap(arr, i, rand.nextInt(i + 1));
}
}
public static <T> void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static int[] shuffled(int[] arr) {
int[] copy = Arrays.copyOf(arr, arr.length);
shuffle(copy);
return copy;
}
Utility Methods
Simple utility methods to copy and convert arrays to lists and vice-versa.
// ================================================================
// Utility methods
// ================================================================
protected static <T> List<T> copyList(List<T> list) {
List<T> copy = new ArrayList<T>(list.size());
for (T item : list) {
copy.add(item);
}
return copy;
}
protected static int[] toPrimitive(Integer[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
return EMPTY_INT_ARRAY;
}
final int[] result = new int[array.length];
for (int i = 0; i < array.length; i++) {
result[i] = array[i].intValue();
}
return result;
}
protected static Integer[] toArray(List<Integer> list) {
return toArray(list, Integer.class);
}
protected static <T> T[] toArray(List<T> list, Class<T> clazz) {
#SuppressWarnings("unchecked")
final T[] arr = list.toArray((T[]) Array.newInstance(clazz, list.size()));
return arr;
}
Range Class
Generates a range of values, similar to Python's range function.
// ================================================================
// Range class for generating a range of values.
// ================================================================
protected static List<Integer> range(int n) {
return toList(new Range(n), new ArrayList<Integer>());
}
protected static <T> List<T> toList(Iterable<T> iterable) {
return toList(iterable, new ArrayList<T>());
}
protected static <T> List<T> toList(Iterable<T> iterable, List<T> destination) {
addAll(destination, iterable.iterator());
return destination;
}
protected static <T> void addAll(Collection<T> collection, Iterator<T> iterator) {
while (iterator.hasNext()) {
collection.add(iterator.next());
}
}
private static class Range implements Iterable<Integer> {
private int start;
private int stop;
private int step;
private Range(int n) {
this(0, n, 1);
}
private Range(int start, int stop) {
this(start, stop, 1);
}
private Range(int start, int stop, int step) {
this.start = start;
this.stop = stop;
this.step = step;
}
#Override
public Iterator<Integer> iterator() {
final int min = start;
final int max = stop / step;
return new Iterator<Integer>() {
private int current = min;
#Override
public boolean hasNext() {
return current < max;
}
#Override
public Integer next() {
if (hasNext()) {
return current++ * step;
} else {
throw new NoSuchElementException("Range reached the end");
}
}
#Override
public void remove() {
throw new UnsupportedOperationException("Can't remove values from a Range");
}
};
}
}
}
Here is a complete solution using the Collections.shuffle approach:
public static void shuffleArray(int[] array) {
List<Integer> list = new ArrayList<>();
for (int i : array) {
list.add(i);
}
Collections.shuffle(list);
for (int i = 0; i < list.size(); i++) {
array[i] = list.get(i);
}
}
Note that it suffers due to Java's inability to smoothly translate between int[] and Integer[] (and thus int[] and List<Integer>).
Using ArrayList<Integer> can help you solving the problem of shuffling without applying much of logic and consuming less time. Here is what I suggest:
ArrayList<Integer> x = new ArrayList<Integer>();
for(int i=1; i<=add.length(); i++)
{
x.add(i);
}
Collections.shuffle(x);
The following code will achieve a random ordering on the array.
// Shuffle the elements in the array
Collections.shuffle(Arrays.asList(array));
from: http://www.programcreek.com/2012/02/java-method-to-shuffle-an-int-array-with-random-order/
You can use java 8 now:
Collections.addAll(list, arr);
Collections.shuffle(list);
cardsList.toArray(arr);
Random rnd = new Random();
for (int i = ar.length - 1; i > 0; i--)
{
int index = rnd.nextInt(i + 1);
// Simple swap
int a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
By the way, I've noticed that this code returns a ar.length - 1 number of elements, so if your array has 5 elements, the new shuffled array will have 4 elements. This happens because the for loop says i>0. If you change to i>=0, you get all elements shuffled.
Here is a solution using Apache Commons Math 3.x (for int[] arrays only):
MathArrays.shuffle(array);
http://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/util/MathArrays.html#shuffle(int[])
Alternatively, Apache Commons Lang 3.6 introduced new shuffle methods to the ArrayUtils class (for objects and any primitive type).
ArrayUtils.shuffle(array);
http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/ArrayUtils.html#shuffle-int:A-
Here is a Generics version for arrays:
import java.util.Random;
public class Shuffle<T> {
private final Random rnd;
public Shuffle() {
rnd = new Random();
}
/**
* Fisher–Yates shuffle.
*/
public void shuffle(T[] ar) {
for (int i = ar.length - 1; i > 0; i--) {
int index = rnd.nextInt(i + 1);
T a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
}
}
Considering that ArrayList is basically just an array, it may be advisable to work with an ArrayList instead of the explicit array and use Collections.shuffle(). Performance tests however, do not show any significant difference between the above and Collections.sort():
Shuffe<Integer>.shuffle(...) performance: 576084 shuffles per second
Collections.shuffle(ArrayList<Integer>) performance: 629400 shuffles per second
MathArrays.shuffle(int[]) performance: 53062 shuffles per second
The Apache Commons implementation MathArrays.shuffle is limited to int[] and the performance penalty is likely due to the random number generator being used.
I saw some miss information in some answers so i decided to add a new one.
Java collections Arrays.asList takes var-arg of type T (T ...). If you pass a primitive array (int array), asList method will infer and generate a List<int[]>, which is a one element list (the one element is the primitive array). if you shuffle this one element list, it won`t change any thing.
So, first you have to convert you primitive array to Wrapper object array. for this you can use ArrayUtils.toObject method from apache.commons.lang. then pass the generated array to a List and finaly shuffle that.
int[] intArr = {1,2,3};
List<Integer> integerList = Arrays.asList(ArrayUtils.toObject(array));
Collections.shuffle(integerList);
//now! elements in integerList are shuffled!
Here's another way to shuffle a list
public List<Integer> shuffleArray(List<Integer> a) {
List<Integer> b = new ArrayList<Integer>();
while (a.size() != 0) {
int arrayIndex = (int) (Math.random() * (a.size()));
b.add(a.get(arrayIndex));
a.remove(a.get(arrayIndex));
}
return b;
}
Pick a random number from the original list and save it in another list.Then remove the number from the original list.The size of the original list will keep decreasing by one until all elements are moved to the new list.
A simple solution for Groovy:
solutionArray.sort{ new Random().nextInt() }
This will sort all elements of the array list randomly which archives the desired result of shuffling all elements.
Using Guava's Ints.asList() it is as simple as:
Collections.shuffle(Ints.asList(array));
Using the Random Class
public static void randomizeArray(int[] arr) {
Random rGenerator = new Random(); // Create an instance of the random class
for (int i =0; i< arr.length;i++ ) {
//Swap the positions...
int rPosition = rGenerator.nextInt(arr.length); // Generates an integer within the range (Any number from 0 - arr.length)
int temp = arr[i]; // variable temp saves the value of the current array index;
arr[i] = arr[rPosition]; // array at the current position (i) get the value of the random generated
arr[rPosition] = temp; // the array at the position of random generated gets the value of temp
}
for(int i = 0; i<arr.length; i++) {
System.out.print(arr[i]); //Prints out the array
}
}
I'm weighing in on this very popular question because nobody has written a shuffle-copy version. Style is borrowed heavily from Arrays.java, because who isn't pillaging Java technology these days? Generic and int implementations included.
/**
* Shuffles elements from {#code original} into a newly created array.
*
* #param original the original array
* #return the new, shuffled array
* #throws NullPointerException if {#code original == null}
*/
#SuppressWarnings("unchecked")
public static <T> T[] shuffledCopy(T[] original) {
int originalLength = original.length; // For exception priority compatibility.
Random random = new Random();
T[] result = (T[]) Array.newInstance(original.getClass().getComponentType(), originalLength);
for (int i = 0; i < originalLength; i++) {
int j = random.nextInt(i+1);
result[i] = result[j];
result[j] = original[i];
}
return result;
}
/**
* Shuffles elements from {#code original} into a newly created array.
*
* #param original the original array
* #return the new, shuffled array
* #throws NullPointerException if {#code original == null}
*/
public static int[] shuffledCopy(int[] original) {
int originalLength = original.length;
Random random = new Random();
int[] result = new int[originalLength];
for (int i = 0; i < originalLength; i++) {
int j = random.nextInt(i+1);
result[i] = result[j];
result[j] = original[i];
}
return result;
}
This is knuth shuffle algorithm.
public class Knuth {
// this class should not be instantiated
private Knuth() { }
/**
* Rearranges an array of objects in uniformly random order
* (under the assumption that <tt>Math.random()</tt> generates independent
* and uniformly distributed numbers between 0 and 1).
* #param a the array to be shuffled
*/
public static void shuffle(Object[] a) {
int n = a.length;
for (int i = 0; i < n; i++) {
// choose index uniformly in [i, n-1]
int r = i + (int) (Math.random() * (n - i));
Object swap = a[r];
a[r] = a[i];
a[i] = swap;
}
}
/**
* Reads in a sequence of strings from standard input, shuffles
* them, and prints out the results.
*/
public static void main(String[] args) {
// read in the data
String[] a = StdIn.readAllStrings();
// shuffle the array
Knuth.shuffle(a);
// print results.
for (int i = 0; i < a.length; i++)
StdOut.println(a[i]);
}
}
There is another way also, not post yet
//that way, send many object types diferentes
public anotherWayToReciveParameter(Object... objects)
{
//ready with array
final int length =objects.length;
System.out.println(length);
//for ready same list
Arrays.asList(objects);
}
that way more easy, depended of the context
The most simple solution for this Random Shuffling in an Array.
String location[] = {"delhi","banglore","mathura","lucknow","chandigarh","mumbai"};
int index;
String temp;
Random random = new Random();
for(int i=1;i<location.length;i++)
{
index = random.nextInt(i+1);
temp = location[index];
location[index] = location[i];
location[i] = temp;
System.out.println("Location Based On Random Values :"+location[i]);
}
Simplest code to shuffle:
import java.util.*;
public class ch {
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
ArrayList<Integer> l=new ArrayList<Integer>(10);
for(int i=0;i<10;i++)
l.add(sc.nextInt());
Collections.shuffle(l);
for(int j=0;j<10;j++)
System.out.println(l.get(j));
}
}
Box from int[] to List<Integer>
Shuffle with Collections.shuffle method
int[] solutionArray = { 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1 };
List<Integer> list = Arrays.stream(solutionArray).boxed().collect(Collectors.toList());
Collections.shuffle(list);
System.out.println(list.toString());
// [1, 5, 5, 4, 2, 6, 1, 3, 3, 4, 2, 6]
You should use Collections.shuffle(). However, you can't directly manipulate an array of primitive types, so you need to create a wrapper class.
Try this.
public static void shuffle(int[] array) {
Collections.shuffle(new AbstractList<Integer>() {
#Override public Integer get(int index) { return array[index]; }
#Override public int size() { return array.length; }
#Override public Integer set(int index, Integer element) {
int result = array[index];
array[index] = element;
return result;
}
});
}
And
int[] solutionArray = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1};
shuffle(solutionArray);
System.out.println(Arrays.toString(solutionArray));
output:
[3, 3, 4, 1, 6, 2, 2, 1, 5, 6, 5, 4]
public class ShuffleArray {
public static void shuffleArray(int[] a) {
int n = a.length;
Random random = new Random();
random.nextInt();
for (int i = 0; i < n; i++) {
int change = i + random.nextInt(n - i);
swap(a, i, change);
}
}
private static void swap(int[] a, int i, int change) {
int helper = a[i];
a[i] = a[change];
a[change] = helper;
}
public static void main(String[] args) {
int[] a = new int[] { 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1 };
shuffleArray(a);
for (int i : a) {
System.out.println(i);
}
}
}
import java.util.ArrayList;
import java.util.Random;
public class shuffle {
public static void main(String[] args) {
int a[] = {1,2,3,4,5,6,7,8,9};
ArrayList b = new ArrayList();
int i=0,q=0;
Random rand = new Random();
while(a.length!=b.size())
{
int l = rand.nextInt(a.length);
//this is one option to that but has a flaw on 0
// if(a[l] !=0)
// {
// b.add(a[l]);
// a[l]=0;
//
// }
//
// this works for every no.
if(!(b.contains(a[l])))
{
b.add(a[l]);
}
}
// for (int j = 0; j <b.size(); j++) {
// System.out.println(b.get(j));
//
// }
System.out.println(b);
}
}
One of the solution is using the permutation to pre-compute all the permutations and stored in the ArrayList
Java 8 introduced a new method, ints(), in the java.util.Random class. The ints() method returns an unlimited stream of pseudorandom int values. You can limit the random numbers between a specified range by providing the minimum and the maximum values.
Random genRandom = new Random();
int num = genRandom.nextInt(arr.length);
With the help of generating the random number, You can iterate through the loop and swap with the current index with the random number..
That's how you can generate a random number with O(1) space complexity.
Without Random solution:
static void randomArrTimest(int[] some){
long startTime = System.currentTimeMillis();
for (int i = 0; i < some.length; i++) {
long indexToSwap = startTime%(i+1);
long tmp = some[(int) indexToSwap];
some[(int) indexToSwap] = some[i];
some[i] = (int) tmp;
}
System.out.println(Arrays.toString(some));
}
In Java we can use Collections.shuffle method to randomly reorder items in a list.
Groovy 3.0.0 adds the shuffle and shuffled methods to a List or array directly.
I need to randomly shuffle the following Array:
int[] solutionArray = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1};
Is there any function to do that?
Using Collections to shuffle an array of primitive types is a bit of an overkill...
It is simple enough to implement the function yourself, using for example the Fisher–Yates shuffle:
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
class Test
{
public static void main(String args[])
{
int[] solutionArray = { 1, 2, 3, 4, 5, 6, 16, 15, 14, 13, 12, 11 };
shuffleArray(solutionArray);
for (int i = 0; i < solutionArray.length; i++)
{
System.out.print(solutionArray[i] + " ");
}
System.out.println();
}
// Implementing Fisher–Yates shuffle
static void shuffleArray(int[] ar)
{
// If running on Java 6 or older, use `new Random()` on RHS here
Random rnd = ThreadLocalRandom.current();
for (int i = ar.length - 1; i > 0; i--)
{
int index = rnd.nextInt(i + 1);
// Simple swap
int a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
}
}
Here is a simple way using an ArrayList:
List<Integer> solution = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
solution.add(i);
}
Collections.shuffle(solution);
Here is a working and efficient Fisher–Yates shuffle array function:
private static void shuffleArray(int[] array)
{
int index;
Random random = new Random();
for (int i = array.length - 1; i > 0; i--)
{
index = random.nextInt(i + 1);
if (index != i)
{
array[index] ^= array[i];
array[i] ^= array[index];
array[index] ^= array[i];
}
}
}
or
private static void shuffleArray(int[] array)
{
int index, temp;
Random random = new Random();
for (int i = array.length - 1; i > 0; i--)
{
index = random.nextInt(i + 1);
temp = array[index];
array[index] = array[i];
array[i] = temp;
}
}
Collections class has an efficient method for shuffling, that can be copied, so as not to depend on it:
/**
* Usage:
* int[] array = {1, 2, 3};
* Util.shuffle(array);
*/
public class Util {
private static Random random;
/**
* Code from method java.util.Collections.shuffle();
*/
public static void shuffle(int[] array) {
if (random == null) random = new Random();
int count = array.length;
for (int i = count; i > 1; i--) {
swap(array, i - 1, random.nextInt(i));
}
}
private static void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
Look at the Collections class, specifically shuffle(...).
You have a couple options here. A list is a bit different than an array when it comes to shuffling.
As you can see below, an array is faster than a list, and a primitive array is faster than an object array.
Sample Durations
List<Integer> Shuffle: 43133ns
Integer[] Shuffle: 31884ns
int[] Shuffle: 25377ns
Below, are three different implementations of a shuffle. You should only use Collections.shuffle if you are dealing with a collection. There is no need to wrap your array into a collection just to sort it. The methods below are very simple to implement.
ShuffleUtil Class
import java.lang.reflect.Array;
import java.util.*;
public class ShuffleUtil<T> {
private static final int[] EMPTY_INT_ARRAY = new int[0];
private static final int SHUFFLE_THRESHOLD = 5;
private static Random rand;
Main Method
public static void main(String[] args) {
List<Integer> list = null;
Integer[] arr = null;
int[] iarr = null;
long start = 0;
int cycles = 1000;
int n = 1000;
// Shuffle List<Integer>
start = System.nanoTime();
list = range(n);
for (int i = 0; i < cycles; i++) {
ShuffleUtil.shuffle(list);
}
System.out.printf("%22s: %dns%n", "List<Integer> Shuffle", (System.nanoTime() - start) / cycles);
// Shuffle Integer[]
start = System.nanoTime();
arr = toArray(list);
for (int i = 0; i < cycles; i++) {
ShuffleUtil.shuffle(arr);
}
System.out.printf("%22s: %dns%n", "Integer[] Shuffle", (System.nanoTime() - start) / cycles);
// Shuffle int[]
start = System.nanoTime();
iarr = toPrimitive(arr);
for (int i = 0; i < cycles; i++) {
ShuffleUtil.shuffle(iarr);
}
System.out.printf("%22s: %dns%n", "int[] Shuffle", (System.nanoTime() - start) / cycles);
}
Shuffling a Generic List
// ================================================================
// Shuffle List<T> (java.lang.Collections)
// ================================================================
#SuppressWarnings("unchecked")
public static <T> void shuffle(List<T> list) {
if (rand == null) {
rand = new Random();
}
int size = list.size();
if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
for (int i = size; i > 1; i--) {
swap(list, i - 1, rand.nextInt(i));
}
} else {
Object arr[] = list.toArray();
for (int i = size; i > 1; i--) {
swap(arr, i - 1, rand.nextInt(i));
}
ListIterator<T> it = list.listIterator();
int i = 0;
while (it.hasNext()) {
it.next();
it.set((T) arr[i++]);
}
}
}
public static <T> void swap(List<T> list, int i, int j) {
final List<T> l = list;
l.set(i, l.set(j, l.get(i)));
}
public static <T> List<T> shuffled(List<T> list) {
List<T> copy = copyList(list);
shuffle(copy);
return copy;
}
Shuffling a Generic Array
// ================================================================
// Shuffle T[]
// ================================================================
public static <T> void shuffle(T[] arr) {
if (rand == null) {
rand = new Random();
}
for (int i = arr.length - 1; i > 0; i--) {
swap(arr, i, rand.nextInt(i + 1));
}
}
public static <T> void swap(T[] arr, int i, int j) {
T tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static <T> T[] shuffled(T[] arr) {
T[] copy = Arrays.copyOf(arr, arr.length);
shuffle(copy);
return copy;
}
Shuffling a Primitive Array
// ================================================================
// Shuffle int[]
// ================================================================
public static <T> void shuffle(int[] arr) {
if (rand == null) {
rand = new Random();
}
for (int i = arr.length - 1; i > 0; i--) {
swap(arr, i, rand.nextInt(i + 1));
}
}
public static <T> void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static int[] shuffled(int[] arr) {
int[] copy = Arrays.copyOf(arr, arr.length);
shuffle(copy);
return copy;
}
Utility Methods
Simple utility methods to copy and convert arrays to lists and vice-versa.
// ================================================================
// Utility methods
// ================================================================
protected static <T> List<T> copyList(List<T> list) {
List<T> copy = new ArrayList<T>(list.size());
for (T item : list) {
copy.add(item);
}
return copy;
}
protected static int[] toPrimitive(Integer[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
return EMPTY_INT_ARRAY;
}
final int[] result = new int[array.length];
for (int i = 0; i < array.length; i++) {
result[i] = array[i].intValue();
}
return result;
}
protected static Integer[] toArray(List<Integer> list) {
return toArray(list, Integer.class);
}
protected static <T> T[] toArray(List<T> list, Class<T> clazz) {
#SuppressWarnings("unchecked")
final T[] arr = list.toArray((T[]) Array.newInstance(clazz, list.size()));
return arr;
}
Range Class
Generates a range of values, similar to Python's range function.
// ================================================================
// Range class for generating a range of values.
// ================================================================
protected static List<Integer> range(int n) {
return toList(new Range(n), new ArrayList<Integer>());
}
protected static <T> List<T> toList(Iterable<T> iterable) {
return toList(iterable, new ArrayList<T>());
}
protected static <T> List<T> toList(Iterable<T> iterable, List<T> destination) {
addAll(destination, iterable.iterator());
return destination;
}
protected static <T> void addAll(Collection<T> collection, Iterator<T> iterator) {
while (iterator.hasNext()) {
collection.add(iterator.next());
}
}
private static class Range implements Iterable<Integer> {
private int start;
private int stop;
private int step;
private Range(int n) {
this(0, n, 1);
}
private Range(int start, int stop) {
this(start, stop, 1);
}
private Range(int start, int stop, int step) {
this.start = start;
this.stop = stop;
this.step = step;
}
#Override
public Iterator<Integer> iterator() {
final int min = start;
final int max = stop / step;
return new Iterator<Integer>() {
private int current = min;
#Override
public boolean hasNext() {
return current < max;
}
#Override
public Integer next() {
if (hasNext()) {
return current++ * step;
} else {
throw new NoSuchElementException("Range reached the end");
}
}
#Override
public void remove() {
throw new UnsupportedOperationException("Can't remove values from a Range");
}
};
}
}
}
Here is a complete solution using the Collections.shuffle approach:
public static void shuffleArray(int[] array) {
List<Integer> list = new ArrayList<>();
for (int i : array) {
list.add(i);
}
Collections.shuffle(list);
for (int i = 0; i < list.size(); i++) {
array[i] = list.get(i);
}
}
Note that it suffers due to Java's inability to smoothly translate between int[] and Integer[] (and thus int[] and List<Integer>).
Using ArrayList<Integer> can help you solving the problem of shuffling without applying much of logic and consuming less time. Here is what I suggest:
ArrayList<Integer> x = new ArrayList<Integer>();
for(int i=1; i<=add.length(); i++)
{
x.add(i);
}
Collections.shuffle(x);
The following code will achieve a random ordering on the array.
// Shuffle the elements in the array
Collections.shuffle(Arrays.asList(array));
from: http://www.programcreek.com/2012/02/java-method-to-shuffle-an-int-array-with-random-order/
You can use java 8 now:
Collections.addAll(list, arr);
Collections.shuffle(list);
cardsList.toArray(arr);
Random rnd = new Random();
for (int i = ar.length - 1; i > 0; i--)
{
int index = rnd.nextInt(i + 1);
// Simple swap
int a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
By the way, I've noticed that this code returns a ar.length - 1 number of elements, so if your array has 5 elements, the new shuffled array will have 4 elements. This happens because the for loop says i>0. If you change to i>=0, you get all elements shuffled.
Here is a solution using Apache Commons Math 3.x (for int[] arrays only):
MathArrays.shuffle(array);
http://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/util/MathArrays.html#shuffle(int[])
Alternatively, Apache Commons Lang 3.6 introduced new shuffle methods to the ArrayUtils class (for objects and any primitive type).
ArrayUtils.shuffle(array);
http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/ArrayUtils.html#shuffle-int:A-
Here is a Generics version for arrays:
import java.util.Random;
public class Shuffle<T> {
private final Random rnd;
public Shuffle() {
rnd = new Random();
}
/**
* Fisher–Yates shuffle.
*/
public void shuffle(T[] ar) {
for (int i = ar.length - 1; i > 0; i--) {
int index = rnd.nextInt(i + 1);
T a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
}
}
Considering that ArrayList is basically just an array, it may be advisable to work with an ArrayList instead of the explicit array and use Collections.shuffle(). Performance tests however, do not show any significant difference between the above and Collections.sort():
Shuffe<Integer>.shuffle(...) performance: 576084 shuffles per second
Collections.shuffle(ArrayList<Integer>) performance: 629400 shuffles per second
MathArrays.shuffle(int[]) performance: 53062 shuffles per second
The Apache Commons implementation MathArrays.shuffle is limited to int[] and the performance penalty is likely due to the random number generator being used.
I saw some miss information in some answers so i decided to add a new one.
Java collections Arrays.asList takes var-arg of type T (T ...). If you pass a primitive array (int array), asList method will infer and generate a List<int[]>, which is a one element list (the one element is the primitive array). if you shuffle this one element list, it won`t change any thing.
So, first you have to convert you primitive array to Wrapper object array. for this you can use ArrayUtils.toObject method from apache.commons.lang. then pass the generated array to a List and finaly shuffle that.
int[] intArr = {1,2,3};
List<Integer> integerList = Arrays.asList(ArrayUtils.toObject(array));
Collections.shuffle(integerList);
//now! elements in integerList are shuffled!
Here's another way to shuffle a list
public List<Integer> shuffleArray(List<Integer> a) {
List<Integer> b = new ArrayList<Integer>();
while (a.size() != 0) {
int arrayIndex = (int) (Math.random() * (a.size()));
b.add(a.get(arrayIndex));
a.remove(a.get(arrayIndex));
}
return b;
}
Pick a random number from the original list and save it in another list.Then remove the number from the original list.The size of the original list will keep decreasing by one until all elements are moved to the new list.
A simple solution for Groovy:
solutionArray.sort{ new Random().nextInt() }
This will sort all elements of the array list randomly which archives the desired result of shuffling all elements.
Using Guava's Ints.asList() it is as simple as:
Collections.shuffle(Ints.asList(array));
Using the Random Class
public static void randomizeArray(int[] arr) {
Random rGenerator = new Random(); // Create an instance of the random class
for (int i =0; i< arr.length;i++ ) {
//Swap the positions...
int rPosition = rGenerator.nextInt(arr.length); // Generates an integer within the range (Any number from 0 - arr.length)
int temp = arr[i]; // variable temp saves the value of the current array index;
arr[i] = arr[rPosition]; // array at the current position (i) get the value of the random generated
arr[rPosition] = temp; // the array at the position of random generated gets the value of temp
}
for(int i = 0; i<arr.length; i++) {
System.out.print(arr[i]); //Prints out the array
}
}
I'm weighing in on this very popular question because nobody has written a shuffle-copy version. Style is borrowed heavily from Arrays.java, because who isn't pillaging Java technology these days? Generic and int implementations included.
/**
* Shuffles elements from {#code original} into a newly created array.
*
* #param original the original array
* #return the new, shuffled array
* #throws NullPointerException if {#code original == null}
*/
#SuppressWarnings("unchecked")
public static <T> T[] shuffledCopy(T[] original) {
int originalLength = original.length; // For exception priority compatibility.
Random random = new Random();
T[] result = (T[]) Array.newInstance(original.getClass().getComponentType(), originalLength);
for (int i = 0; i < originalLength; i++) {
int j = random.nextInt(i+1);
result[i] = result[j];
result[j] = original[i];
}
return result;
}
/**
* Shuffles elements from {#code original} into a newly created array.
*
* #param original the original array
* #return the new, shuffled array
* #throws NullPointerException if {#code original == null}
*/
public static int[] shuffledCopy(int[] original) {
int originalLength = original.length;
Random random = new Random();
int[] result = new int[originalLength];
for (int i = 0; i < originalLength; i++) {
int j = random.nextInt(i+1);
result[i] = result[j];
result[j] = original[i];
}
return result;
}
This is knuth shuffle algorithm.
public class Knuth {
// this class should not be instantiated
private Knuth() { }
/**
* Rearranges an array of objects in uniformly random order
* (under the assumption that <tt>Math.random()</tt> generates independent
* and uniformly distributed numbers between 0 and 1).
* #param a the array to be shuffled
*/
public static void shuffle(Object[] a) {
int n = a.length;
for (int i = 0; i < n; i++) {
// choose index uniformly in [i, n-1]
int r = i + (int) (Math.random() * (n - i));
Object swap = a[r];
a[r] = a[i];
a[i] = swap;
}
}
/**
* Reads in a sequence of strings from standard input, shuffles
* them, and prints out the results.
*/
public static void main(String[] args) {
// read in the data
String[] a = StdIn.readAllStrings();
// shuffle the array
Knuth.shuffle(a);
// print results.
for (int i = 0; i < a.length; i++)
StdOut.println(a[i]);
}
}
There is another way also, not post yet
//that way, send many object types diferentes
public anotherWayToReciveParameter(Object... objects)
{
//ready with array
final int length =objects.length;
System.out.println(length);
//for ready same list
Arrays.asList(objects);
}
that way more easy, depended of the context
The most simple solution for this Random Shuffling in an Array.
String location[] = {"delhi","banglore","mathura","lucknow","chandigarh","mumbai"};
int index;
String temp;
Random random = new Random();
for(int i=1;i<location.length;i++)
{
index = random.nextInt(i+1);
temp = location[index];
location[index] = location[i];
location[i] = temp;
System.out.println("Location Based On Random Values :"+location[i]);
}
Simplest code to shuffle:
import java.util.*;
public class ch {
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
ArrayList<Integer> l=new ArrayList<Integer>(10);
for(int i=0;i<10;i++)
l.add(sc.nextInt());
Collections.shuffle(l);
for(int j=0;j<10;j++)
System.out.println(l.get(j));
}
}
Box from int[] to List<Integer>
Shuffle with Collections.shuffle method
int[] solutionArray = { 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1 };
List<Integer> list = Arrays.stream(solutionArray).boxed().collect(Collectors.toList());
Collections.shuffle(list);
System.out.println(list.toString());
// [1, 5, 5, 4, 2, 6, 1, 3, 3, 4, 2, 6]
You should use Collections.shuffle(). However, you can't directly manipulate an array of primitive types, so you need to create a wrapper class.
Try this.
public static void shuffle(int[] array) {
Collections.shuffle(new AbstractList<Integer>() {
#Override public Integer get(int index) { return array[index]; }
#Override public int size() { return array.length; }
#Override public Integer set(int index, Integer element) {
int result = array[index];
array[index] = element;
return result;
}
});
}
And
int[] solutionArray = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1};
shuffle(solutionArray);
System.out.println(Arrays.toString(solutionArray));
output:
[3, 3, 4, 1, 6, 2, 2, 1, 5, 6, 5, 4]
public class ShuffleArray {
public static void shuffleArray(int[] a) {
int n = a.length;
Random random = new Random();
random.nextInt();
for (int i = 0; i < n; i++) {
int change = i + random.nextInt(n - i);
swap(a, i, change);
}
}
private static void swap(int[] a, int i, int change) {
int helper = a[i];
a[i] = a[change];
a[change] = helper;
}
public static void main(String[] args) {
int[] a = new int[] { 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1 };
shuffleArray(a);
for (int i : a) {
System.out.println(i);
}
}
}
import java.util.ArrayList;
import java.util.Random;
public class shuffle {
public static void main(String[] args) {
int a[] = {1,2,3,4,5,6,7,8,9};
ArrayList b = new ArrayList();
int i=0,q=0;
Random rand = new Random();
while(a.length!=b.size())
{
int l = rand.nextInt(a.length);
//this is one option to that but has a flaw on 0
// if(a[l] !=0)
// {
// b.add(a[l]);
// a[l]=0;
//
// }
//
// this works for every no.
if(!(b.contains(a[l])))
{
b.add(a[l]);
}
}
// for (int j = 0; j <b.size(); j++) {
// System.out.println(b.get(j));
//
// }
System.out.println(b);
}
}
One of the solution is using the permutation to pre-compute all the permutations and stored in the ArrayList
Java 8 introduced a new method, ints(), in the java.util.Random class. The ints() method returns an unlimited stream of pseudorandom int values. You can limit the random numbers between a specified range by providing the minimum and the maximum values.
Random genRandom = new Random();
int num = genRandom.nextInt(arr.length);
With the help of generating the random number, You can iterate through the loop and swap with the current index with the random number..
That's how you can generate a random number with O(1) space complexity.
Without Random solution:
static void randomArrTimest(int[] some){
long startTime = System.currentTimeMillis();
for (int i = 0; i < some.length; i++) {
long indexToSwap = startTime%(i+1);
long tmp = some[(int) indexToSwap];
some[(int) indexToSwap] = some[i];
some[i] = (int) tmp;
}
System.out.println(Arrays.toString(some));
}
In Java we can use Collections.shuffle method to randomly reorder items in a list.
Groovy 3.0.0 adds the shuffle and shuffled methods to a List or array directly.
public class intersect {
public static void find(int[] a, int[] b, int[] acc)
{
int position = 0;
for (int j = 0; j < a.length; j++) {
for (int k = 0; k<b.length; k++) {
if (a[j] == b[k]) {
acc[position] = b[k];
position++;
}
}
}
System.out.println(java.util.Arrays.toString(acc));
}
public static void main (String[] s)
{
int[] acc = new int[2];
int[] a = {1,2,3};
int[] b = {2,3,4};
find(a, b, acc);
}
}
I have written the above code to solve the problem.
But if you see, the function is very limited because I have to change the length of the acc every time. That means I have to know how many elements are intersecting. In this case, the array {1,2,3} and {2,3,4} have {2,3} in common, so the length of the acc would be 2.
I am sure there are millions of ways of tackling this problem, but I cannot seem to think of a way of fixing this.
Please help!
If your professor wants you to use arrays, you can use the following method:
public static int[] resize(int[] arr)
{
int len = arr.length;
int[] copy = new int[len+1];
for (int i = 0; i < len; i++)
{
copy[i] = arr[i];
}
return copy;
}
This will increase the size of the array by 1. You can use that instead. By the way, you're not using the fact that they're sorted in your find() method. What you should do is this:
public static void find(int[] a, int[] b, int[] acc)
{
int a_index = 0, b_index = 0, acc_index = -1;
int a_element, b_element;
while (a_index < a.length && b_index < b.length)
{
a_element = a[a_index]; b_element = b[b_index];
if (a_element == b_element)
{
acc = resize(acc);
acc[++acc_index] = a_element;
a_index++; b_index++;
} else if (b_element < a_element) {
b_index++;
} else {
a_index++;
}
}
System.out.println(java.util.Arrays.toString(acc));
}
This method is more efficient now. Working example.
To find intersection of 2 sorted arrays, follow the below approach :
1) Use two index variables i and j, initial values with 0
2) If array1 is smaller than array2 then increment i.
3) If array1 is greater than array2 then increment j.
4) If both are same then print any of them and increment both i and j.
check this link for more information
https://www.geeksforgeeks.org/union-and-intersection-of-two-sorted-arrays-2/
public class FindIntersection {
static void findInterSection(int array1[], int array2[], int array1NoOfElements, int
array2NoOfElements) {
int i = 0, j = 0;
while (i < array1NoOfElements && j < array2NoOfElements) {
if (array1[i] < array2[j]) {
i++;
} else if (array2[j] < array1[i]) {
j++;
}
// if both array elements are same
else {
System.out.println(array2[j++] + " ");
i++;
}
}
}
public static void main(String[] args)
{
int myFirstArray[] = { 1, 2, 4, 5, 5 };
int mySecondArray[] = { 2, 3, 5, 7 };
int m = myFirstArray.length;
int n = mySecondArray.length;
findInterSection(myFirstArray, mySecondArray, m, n);
}
}
Make your intersection array's size the size of the smaller of your original arrays. That way, you won't ever have to increase it's capacity.
Then you can use Arrays.copy to transfer your results into an appropriately sized array.
Not sure if this is the best solution, but you don't need to hard-code the size of the intersection ahead of time (which is one thing you were concerned about).
As you iterate through both arrays, you can add elements found in both sets to a StringBuilder (along with some delimiter, I used a comma in the example below). Once you're finished, you can call toString() & then split() using the delimiter afterwards to get a String[]. At that point, you can put convert those String objects to int primitives & return an int[].
public class Scratch {
public static void main(String[] s) {
int[] a = {1, 2, 3};
int[] b = {2, 3, 4};
int[] intersection = findIntersection(a, b);
System.out.println(Arrays.toString(intersection));
}
public static int[] findIntersection(int[] a, int[] b) {
StringBuilder intersectionStringBuilder = new StringBuilder();
for (int j = 0; j < a.length; j++) {
for (int k = 0; k < b.length; k++) {
if (a[j] == b[k])
intersectionStringBuilder.append(a[j] + ",");
}
}
String[] intersectionStringArray = intersectionStringBuilder.toString().split(",");
int[] intersection = new int[intersectionStringArray.length];
for (int current = 0; current < intersectionStringArray.length; current++) {
intersection[current] = Integer.parseInt(intersectionStringArray[current]);
}
return intersection;
}
}
for(int i=0;i<arr1.length;i++){
for(int j=0;j<arr2.length;j++){
if(arr1[i]==arr2[j] && !index.contains(j)){
list.add(arr1[i]);
index.add(j);
break;
}
}
}
int result[]=new int[list.size()];
int k=0;
for(int i:list){
result[k]=i;
k++;
}
for(int i=0;i<result.length;i++){
System.out.println(result[i]);
}
return result;
}
I have designed a recursive algorithm to find the number of children in a string. The string is actually an array such as [1,0,1,0,1]. There three possible children of this string which are [0,0,1,0,1], [1,0,0,0,1] and [1,0,1,0,0]. Thus the criteria for creating the children is to decrement only one non-zero entry in the string. Since there are three non-zero entries in [1,0,1,0,1] so three possible children. Continuing in this fashion each children can now have two possible children and so on. The recursion stop when there is only one non-zero entry in the string.
This is my code:
public class Recursion {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
int[] c={1,0,1,0,1};
System.out.println(num(c));
}
private static int num(int[] v){
if(numChildren(v)==1){
return 1;
}
else{
int[][] ge=children(v);
for(int[] e:ge){
return 1+num(e);
}
System.out.print("this return should never execute");
return 0;
}
}
private static int numChildren(int[] val){
int sum=0;
for(int i=0;i<val.length;i++){
if(val[i]!=0){
sum+=1;
}
}
return sum;
}
private static int[][] children(int[] p){
int pChildern=numChildren(p);
int[] d=new int[pChildern];
int[][] r=new int[pChildern][];
int c=0;
for(int j=0;j<p.length;j++){
if(p[j]!=0){
d[c]=j;
c++;
}
}
for(int i=0;i<pChildern;i++){
p[d[i]]--;
r[i]=p.clone();
p[d[i]]++;
}
return r;
}
}
My code does execute but doesn't produce correct result. It should print 6 but it prints 3.
Can any one suggest me what is wrong with this code?
// Returns size of subtree including the root
int getNumChilds(Node node) {
int count = 1;
for (Node child : node.getChildren()) {
count += getNumChilds(child);
}
return count;
}
I didn't really go into details, but this block looks weird:
int[][] ge=children(v);
for(int[] e:ge){
return 1+num(e);
}
System.out.print("this return should never execute");
return 0;
You want to sum up all its children here, but you return too early. It should be something like this:
int[][] ge=children(v);
int totChild = 0;
for(int[] e:ge){
totChild = totChild + num(e);
}
return totChild;
I think following code might be well suited to your needs.
{1, 0, 1, 0, 1} --> gives 7 (2 x 2 x 2 - 1)
{1, 1, 1, 1, 1} --> gives 31 (2 x 2 x 2 x 2 x 2 - 1)
{4, 4, 1, 1, 1} --> gives 199 (5 x 5 x 2 x 2 x 2 - 1)
-1 is to remove {0, 0, 0, 0, 0} from children.
public class Recursion {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
int[] c={4,4,1,1,1};
System.out.println(num(c, 0));
}
private static void print(int[] v) {
System.out.print("[");
for ( int i = 0; i < v.length; ++i ) {
System.out.print(v[i] + ",");
}
System.out.println("] ");
}
private static int num(int[] v, int k){
if(numChildren(v)==1){
return 1;
}
else{
int r = 1;
for ( int i = k; i < v.length; ++i ) {
if ( v[i] > 0) {
int o = v[i];
v[i] = o - 1;
print(v);
r += num(v, i);
v[i] = o;
}
}
return r;
}
}
private static int numChildren(int[] val){
int sum=0;
for(int i=0;i<val.length;i++){
if(val[i]!=0){
sum+=1;
}
}
return sum;
}
}
I have this code for heapSort which works fine. I also understand how the algorithm works when the start index is 1 and not 0. My question is that the maxheap method by itself below works for all indices greater than zero, but not at index 0. however the Sort method calls with index 0 and the array gets sorted. when index i = 0, the call to maxheap will have left=2*i=0 and right=2*i+1=1, which leads to i and left being same at 0 and right at index 1, meaning that the the root and left are same and has only right tree. this is confusing to me. Here is the code:
public class HeapSort
{
private static int heapSize;
/* Sort Function */
public static void sort(int arr[])
{
heapify(arr);
System.out.println("arrays is "+Arrays.toString(arr));
for (int i = heapSize; i > 0; i--)
{
swap(arr,0, i);
heapSize = heapSize-1;
maxheap(arr, 0);
}
}
/* Function to build a heap */
public static void heapify(int arr[])
{
heapSize = arr.length-1;
for (int i = heapSize/2; i >= 0; i--)
maxheap(arr, i);
System.out.println("finished maxheap");
}
/* Function to swap largest element in heap */
public static void maxheap(int arr[], int i)
{
//heapSize = arr.length-1;// comment this out if you use sort method since `heapSize` is defined at heapfy method
int left = 2*i ;
int right = 2*i + 1;
int max = i;
if (left <= heapSize && arr[left] > arr[i])
max = left;
if (right <= heapSize && arr[right] > arr[max])
max = right;
//System.out.printf("i is %s; left is %s; right is %s; max is %s%n",i,left,right,max);
if (max != i)
{
swap(arr, i, max);
maxheap(arr, max);
}
}
/* Function to swap two numbers in an array */
public static void swap(int arr[], int i, int j)
{
//System.out.println("called");
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
/* Main method */
public static void main(String[] args)
{
System.out.println("Heap Sort Test\n");
/* Call method sort */
int[] arr = {34,5,6,712,90};
sort(arr);
System.out.println("\nElements after sorting ");
System.out.println(Arrays.toString(arr));
/* Call method maxheap; make sure you comment in heapSize=arr.length in the method */
int[] arr2 = {2,1,3};
maxheap(arr2, 1);
//maxheap(arr2,0) will not work, i.e gives same arr2 as output
System.out.println(Arrays.toString(arr2));
}
}
EDIT:
These two blogs uses the same code:
sanfoundry.com/java-program-implement-heap-sort,
sciencetechpedia.blogspot.com/2012/11/heap-sort-using-java.html
If your start index = 0 of your array, the method to calculate the left child index and the right child index should like this:
private static int getLeftCh (int index) {
return index * 2 + 1;
}
private static int getRightCh (int index) {
return index * 2 + 2;
}
[My Heapsort like this]
public class HeapSort {
// Heap sort the givenArray.
// Time complexity = O(nlgn).
// From max to min.
private static int getLeftCh (int index) {
return index * 2 + 1;
}
private static int getRightCh (int index) {
return index * 2 + 2;
}
private static void exchange (int[] givenArray, int firstIndex, int secondIndex) {
int tempElem = givenArray[firstIndex];
givenArray[firstIndex] = givenArray[secondIndex];
givenArray[secondIndex] = tempElem;
}
private static void minHeapify (int[] givenArray, int size, int index) {
int left = getLeftCh(index);
int right = getRightCh(index);
int minIndex = index;
if (left < size && givenArray[left] <= givenArray[index]) minIndex = left;
else minIndex = index;
if (right < size && givenArray[right] < givenArray[minIndex]) minIndex = right;
if (index != minIndex) {
// Exchange the givenArray[index] and the givenArray[minIndex].
exchange(givenArray, index, minIndex);
// Do recrusion on from minIndex.
minHeapify (givenArray, size, minIndex);
}
}
private static void buildMinHeap (int[] givenArray) {
int size = givenArray.length;
for (int i = (size / 2 - 1); i >= 0; i --) {
// Do min-heapify on the i.
minHeapify (givenArray, size, i);
}
}
public static void heapSortFromMaxToMin (int[] givenArray) {
int size = givenArray.length;
// Build the max heap.
buildMinHeap(givenArray);
// Do the max-heapify on the remaining part of the minheap.
for (int i = size - 1; i >= 0; i --) {
// Move the current first elem back to the last one among the current scope.
exchange (givenArray, 0, size - 1);
// Do minHeapify on the remaining part of the heap from the index = 0.
minHeapify (givenArray, (-- size), 0);
}
}
// Show array.
public static void showArray (int[] givenArray) {
int size = givenArray.length;
for (int i = 0; i < size; i ++)
System.out.print(String.format("%-6d", givenArray[i]));
System.out.println();
}
// Main method to test.
public static void main (String[] args) {
// Test data: {5, 4, 8, 0, 2, -5, 8, 0}.
int[] givenArray = {5, 4, 8, 0, 2, -5, 8, 0};
// Test the heap sort on the givenArray, from max to min.
heapSortFromMaxToMin (givenArray);
showArray(givenArray);
}
}
When your array is 0-based, the child nodes are at (2*i)+1 and (2*i)+2.
To generalize, child nodes are at (2*i)+1-array_base and (2*i)+2-array_base.