實現該功能的方法為,只需要多聲明一個數組存儲排序索引即可,然后在實際排序的時候,索引數組和數組同時變更。
需要注意的是,原本排序程序中的很多地方需要大改。
快速排序(不存儲索引):
private static void quickSort(int[] keys, int begin, int end) { if (begin >= 0 && begin < keys.length && end >= 0 && end < keys.length && begin < end) { int i = begin, j = end; int vot = keys[i]; while (i != j) { while(i < j && keys[j] >= vot) j--; if(i < j) keys[i++] = keys[j]; while(i < j && keys[i] <= vot) i++; if(i < j) keys[j--] = keys[i]; } keys[i] = vot; quickSort(keys, begin, j-1); quickSort(keys, i+1, end); } }
由於需要存儲索引數組,因此涉及到數組的初始化問題,而這又是一個遞歸程序,因此需要寫一個函數調用該遞歸函數。在這個函數里面初始化索引數組,並返回排序后的索引作為函數返回結果:
private static int[] quickSort(int[] keys) { int[] indices = new int[keys.length]; for (int i = 0; i < keys.length; i++) { indices[i] = i; } quickSort(keys, 0, keys.length-1, indices); return indices; }
然后原本的
void quickSort(int[] keys, int begin, int end)
改為:
void quickSort(keys, 0, keys.length-1, indices)
另外,排序程序里面的 keys[i++]=keys[j] 應該改掉了,完整函數如下,可以體會體會
private static void quickSort(int[] keys, int begin, int end, int[] indices) { if (begin >= 0 && begin < keys.length && end >= 0 && end < keys.length && begin < end) { int i = begin, j = end; int vot = keys[i]; int temp = indices[i]; while (i != j) { while(i < j && keys[j] >= vot) j--; if(i < j) { keys[i] = keys[j]; indices[i] = indices[j]; i++; } while(i < j && keys[i] <= vot) i++; if(i < j) { keys[j] = keys[i]; indices[j] = indices[i]; j--; } } keys[i] = vot; indices[i] = temp; quickSort(keys, begin, j-1, indices); quickSort(keys, i+1, end, indices); } }
排序
public static void main(String[] args) { int[] arr = {10,7,2,4,3,8,9,19}; System.out.println("----排序前----"); System.out.println(Arrays.toString(arr)); int[] index = quickSort(arr); System.out.println("----排序后----"); System.out.println(Arrays.toString(arr)); System.out.println(Arrays.toString(index)); }
結果:
----排序前----
[10, 7, 2, 4, 3, 8, 9, 19]
----排序后----
[2, 3, 4, 7, 8, 9, 10, 19]
[2, 4, 3, 1, 5, 6, 0, 7]
通過排序前的索引,能夠找到數組排序前的位置。由於有的問題中排序只是為了解決問題而采取的一個手段,實際上並不需要排序,那么就需要找到數組排序之前的位置。