public class ShellSort {
public static void main(String[] args) throws Exception {
int[] numbers = ArrayTools.getRandomInts(9, -5, 5, true);
ArrayTools.printInts(numbers);
ArrayTools.printInts(shellSort(numbers));
}
public static int[] shellSort(int[] numbers) {
int d = numbers.length;
int temp;
int j;
while (true) {
d = d / 2;
for (int x = 0; x < d; x++) {
for (int i = x; i < numbers.length; i += d) {
temp = numbers[i];
for (j = i; j >= d && temp < numbers[j - d]; j -= d) {
numbers[j] = numbers[j - d];
}
numbers[j] = temp;
}
}
if (d == 1) {
return numbers;
}
}
}
}
/**
* @param length
* @param start
* inclusive.
* @param end
* exclusive.
* @param repeat
* repeat elements.
* @return
* @throws NumberWrongException
*/
public static int[] getRandomInts(int length, int start, int end, boolean repeat) throws NumberWrongException {
if (length < 2)
throw new NumberWrongException("The length must be larger than 1.");
if (start >= end)
throw new NumberWrongException("start must be smaller than end.");
int range = end - start;
if (length > range)
throw new NumberWrongException("length must be smaller than range.");
Random random = new Random();
int[] numbers = new int[length];
if (length * 2 > range) {
LinkedList<Integer> ll = new LinkedList<Integer>();
for (int i = start; i < end; i++) {
ll.add(i);
}
numbers = new int[length];
for (int j = 0; j < length; j++) {
if (repeat) {
numbers[j] = ll.get((int) (random.nextFloat() * ll.size()));
} else {
numbers[j] = ll.remove((int) (random.nextFloat() * ll.size()));
}
}
} else {
numbers[0] = start + (int) (range * random.nextFloat());
for (int i = 1; i < length; i++) {
int temp = start + (int) (range * random.nextFloat());
int j = 0;
while (j < i) {
if (!repeat && temp == numbers[j]) {
temp = start + (int) (range * random.nextFloat());
j = 0;
continue;
}
j++;
}
numbers[j] = temp;
}
}
return numbers;
}