My friend was asked a question in his interview:
The interviewer gave him an array of unsorted numbers and asked him to sort. The restriction is that the number of writes should be minimized while there is no limitation on the number of reads.
My friend was asked a question in his interview:
The interviewer gave him an array of unsorted numbers and asked him to sort. The restriction is that the number of writes should be minimized while there is no limitation on the number of reads.
If the numbers are in a specific range, the task may be done in O(n) compute time, which is a special case of ordering, its done by creating an array and mapping each number to the specified position.
If the numbers are not in a range, the the best ways to do this is using either QuickSort or HeapSort, which sorts int O(Log2N) both, but some preffer QuickSort, like me.
You can find a QuickSort implementation in any language in almost every place, just Google it and you'll find it in seconds.
An adaptation of HeapSort is available when organizing external data, means data that is not in memmory, but in hard disk, most common when dealing with huge arrays.
Hope I can be of help Best Regards and best of luck!
If the array is shorter (ie less than about 100 elements) a Selection sort is often the best choice if you also want to reduce the number of writes.
From wikipedia:
Another key difference is that selection sort always performs Θ(n) swaps, while insertion sort performs Θ(n2) swaps in the average and worst cases. Because swaps require writing to the array, selection sort is preferable if writing to memory is significantly more expensive than reading. This is generally the case if the items are huge but the keys are small. Another example where writing times are crucial is an array stored in EEPROM or Flash. There is no other algorithm with less data movement.
For larger arrays/lists Quicksort and friends will provide better performance, but may still likely need more writes than a selection sort.
If you're interested this is a fantastic sort visualization site that allows you to watch specific sort algorithms do their job and also "race" different sort algorithms against each other.
You can use a very naive algorithm that satisfies what you need.
The algorithm should look like this:
i = 0
do
search for the minimum in range [i..n)
swap a[i] with a[minPos]
i = i + 1
repeat until i = n.
The search for the minimum can cost you almost nothing, the swap costs you 3 writes, the i++ costs you 1..
This is named selection sort as stated by ash. (Sorry, I didn't knew it was selection sort :( )
The ordering I meant in O(n) is like the selection sort(the previous post) useful when you have a small range of keys (or you are ordering numbers between 2 ranges)
If you have a number array where numbers will be between -10 and 100, then you can create an array of 110 and be sure that all numbers will fit in there, if you consider repeated numbers the idea is the same, but you will have lists instead of numbers in the sorted array
the pseudo-idea is like this
N: max value of your array
tosort //array to be sorted
sorted = int[N]
for i = 0 to length(tosort)
do
sorted[tosort[i]]++;
end
finalarray = int[length(tosort)]
k = 0
for i = 0 to N
do
if ( sorted[i] > 0 )
finalarray[k] = i
k++;
endif
end
finalarray will have the final sorted array and you will have o(N) write operations, where N is the range of the array. Once again, this is useful when using keys inside a specific range, but perhaps its your case.
Best regards and good luck!
One option for large arrays is as follows (assuming n elements):
To sort in-place, in step 3 you should instead identify the cycles in the permutation, and 'rotate' them as necessary to result in sorted order.
Selection sort is not the right algorithm here. Selection sort will swap values, making up to two writes per selection, giving a maximum of 2n writes per sort.
An algorithm that's twice as good as selection sort is "cycle" sort (edit: it appears it's already been invented, and with probably a faster algorithm than here), which does not swap. Cycle sort will give a maximum of n writes per sort. The number of writes is absolutely minimized. It will only write a number once to its final destination, and only then if it's not already there.
It is based on the idea that all permutations are products of cycles and you can simply cycle through each cycle and write each element to its proper place once.
import java.util.Random;
import java.util.Collections;
import java.util.Arrays;
public class CycleSort {
public static final <T extends Comparable<T>> int cycleSort(T[] array) {
int writes = 0;
for (int cycleStart = 0; cycleStart < array.length; cycleStart++) {
T element = array[cycleStart];
int from = cycleStart;
do {
int to = 0;
for (int i = 0; i < array.length; i++) {
if (i != cycleStart && array[i].compareTo(element) < 0) to++;
}
if (from != to) {
while (from != to && element.compareTo(array[to]) == 0) to++;
if (from != to) {
final T temp = array[to];
array[to] = element;
element = temp;
writes++;
from = to;
}
}
} while (cycleStart != from);
}
return writes;
}
public static final void main(String[] args) {
final Random rand = new Random();
final Integer[] array = new Integer[8];
for (int i = 0; i < array.length; i++) { array[i] = rand.nextInt(8); }
for (int iteration = 0; iteration < 10; iteration++) {
System.out.printf("array: %s ", Arrays.toString(array));
final int writes = cycleSort(array);
System.out.printf("sorted: %s writes: %d\n", Arrays.toString(array), writes);
Collections.shuffle(Arrays.asList(array));
}
}
}
A few example runs :
array: [6, 2, 4, 1, 2, 5, 1, 3] sorted: [1, 1, 2, 2, 3, 4, 5, 6] writes: 8 array: [5, 3, 4, 6, 2, 1, 1, 2] sorted: [1, 1, 2, 2, 3, 4, 5, 6] writes: 8 array: [2, 6, 1, 4, 3, 1, 5, 2] sorted: [1, 1, 2, 2, 3, 4, 5, 6] writes: 6 array: [4, 1, 1, 5, 2, 2, 3, 6] sorted: [1, 1, 2, 2, 3, 4, 5, 6] writes: 6 array: [1, 1, 5, 4, 2, 6, 2, 3] sorted: [1, 1, 2, 2, 3, 4, 5, 6] writes: 6 array: [2, 6, 1, 3, 1, 4, 5, 2] sorted: [1, 1, 2, 2, 3, 4, 5, 6] writes: 6 array: [4, 1, 6, 3, 2, 1, 5, 2] sorted: [1, 1, 2, 2, 3, 4, 5, 6] writes: 6 array: [2, 1, 1, 3, 2, 6, 5, 4] sorted: [1, 1, 2, 2, 3, 4, 5, 6] writes: 6 array: [4, 1, 3, 2, 1, 2, 6, 5] sorted: [1, 1, 2, 2, 3, 4, 5, 6] writes: 6 array: [5, 6, 1, 3, 1, 2, 2, 4] sorted: [1, 1, 2, 2, 3, 4, 5, 6] writes: 8
array: [7, 1, 1, 1, 7, 4, 2, 4] sorted: [1, 1, 1, 2, 4, 4, 7, 7] writes: 5 array: [1, 2, 4, 7, 7, 1, 1, 4] sorted: [1, 1, 1, 2, 4, 4, 7, 7] writes: 7 array: [1, 1, 1, 7, 4, 4, 2, 7] sorted: [1, 1, 1, 2, 4, 4, 7, 7] writes: 2 array: [7, 1, 4, 2, 1, 4, 7, 1] sorted: [1, 1, 1, 2, 4, 4, 7, 7] writes: 4 array: [1, 4, 4, 1, 7, 7, 2, 1] sorted: [1, 1, 1, 2, 4, 4, 7, 7] writes: 7 array: [1, 2, 4, 7, 7, 4, 1, 1] sorted: [1, 1, 1, 2, 4, 4, 7, 7] writes: 6 array: [1, 1, 4, 2, 4, 7, 1, 7] sorted: [1, 1, 1, 2, 4, 4, 7, 7] writes: 3 array: [7, 1, 4, 1, 7, 4, 2, 1] sorted: [1, 1, 1, 2, 4, 4, 7, 7] writes: 6 array: [4, 4, 1, 1, 7, 7, 2, 1] sorted: [1, 1, 1, 2, 4, 4, 7, 7] writes: 7 array: [7, 1, 1, 7, 4, 1, 4, 2] sorted: [1, 1, 1, 2, 4, 4, 7, 7] writes: 5