快速排序的思路是选定一个标志元素,将比这个元素小的所有元素放在一边,比其大的放在另外一边。
然后发分别对两个子数组进行同样的操作,直到子数组元素数为1时,整体数组就排好序了。
package test.sort;
public class QuickSort {
public static void sortA(int[] arrayToSort, int left, int right, String partStr) {
int flag;
int flagIndex;
int count = right - left + 1;
if (count <= 1) {
return; //当元素数量小于等于1时,待排序数组已经有序,直接返回
}
flag = arrayToSort[(left + right)/2];
flagIndex = (left + right)/2;
int leftIndex = left;
int rightIndex = right;
/*
* 如果每次申请一个新的数组来分大小,那么会造成空间的浪费,因此直接在
* 被排序数组上进行分大小操作。
*
* 由于直接选固定位置的元素作为flag(此处为中间元素),无法得知这个元素
* 在整个有序数组中位置(正中间?靠前?靠后?)因此没法确定循环计数,需要使用while
*
* 由于在原数组上遍历,因此需要由两端交替遍历,才能完成大小交换;
* 否则由于从一端遍历到需要交换元素时,不能确定交换的位置,那么仍需要申请临时数组存储。
*
* 继续遍历一端时,我们首先确保此端已遍历的元素是已经满足大小要求的;
* 其次确保: 需要遍历的元素数量 + 已遍历的元素数量 = 总元素数量
* 因此在遍历一端,遇到交换操作,直接与flag的元素交换,来保证从另一端遍历时满足此条件。
* */
while (leftIndex < rightIndex) {
while(arrayToSort[leftIndex] < flag) {
leftIndex++; //从左端遍历,略过满足大小要求元素
}
//改变flag元素位置,以便从另一端遍历时仅剩余未遍历过的元素
arrayToSort[flagIndex] = arrayToSort[leftIndex];
arrayToSort[leftIndex] = flag;
flagIndex = leftIndex;
while(arrayToSort[rightIndex] > flag) {
rightIndex--; //从右端遍历,略过满足大小要求元素
}
//改变flag元素位置,以便从另一端遍历时仅剩余未遍历过的元素
arrayToSort[flagIndex] = arrayToSort[rightIndex];
arrayToSort[rightIndex] = flag;
flagIndex = rightIndex;
}
sortA(arrayToSort, left, flagIndex - 1, "left"); //排序左子数组
sortA(arrayToSort, flagIndex + 1, right, "right"); //排序右子数组
}
public static void main(String[] args) {
int[] a = {13, 12, 11, 10, 9, 8, 35, 6, 5, 4, 3, 2, 1};
sortA(a, 0, a.length - 1, "all");
for (int n = 0; n < a.length; n++) {
System.out.println(a[n]);
}
}
}