vlambda博客
学习文章列表

【每周一算】十大经典排序算法之快速排序

排序的时间复杂度

算法名称 平均时间复杂 空间复杂度  定性
快速排序 O(nlogn) O(logn) 不稳定

快速排序过程

1. 从数列中挑出一个元素,称为 “基准”(pivot);2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

代码实现


public class QuickSortTest01 {


public static void quicksort(int[] arr, int left, int right) {

if (left >= right) {
return;
}

int flag = left;
int start = left;
int end = right;

while (left < right) {
while ((left < right) && (arr[right] >= arr[flag])) {
right--;
}
if (arr[right] < arr[flag]) {
int tmp = arr[right];
arr[right] = arr[flag];
arr[flag] = tmp;
flag = right;
}

while ((left < right) && (arr[left] <= arr[left])) {
left++;
}

if (arr[left] > arr[flag]) {
int tmp = arr[left];
arr[left] = arr[flag];
arr[flag] = tmp;
flag = left;
}
}

quicksort(arr, start, flag - 1);
quicksort(arr, flag + 1, end);


}


/**
* 占位法
*
* @param arr
* @param left
* @param right
*/
public static void quick_sort(int[] arr, int left, int right) {
if (left < right) {

//Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
int i = left, j = right, x = arr[left];

while (i < j) {
while (i < j && arr[j] >= x) // 从右向左找第一个小于x的数
j--;
if (i < j) {
arr[i++] = arr[j];
}

while (i < j && arr[i] < x) // 从左向右找第一个大于等于x的数
i++;
if (i < j) {
arr[j--] = arr[i];
}
}
arr[i] = x;
quick_sort(arr, left, i - 1); // 递归调用
quick_sort(arr, i + 1, right);
}
}

public static void main(String[] args) {
int[] arr = new int[] {23, 100, 10, 5, 2, 200};

quick_sort(arr, 0, arr.length - 1);


System.out.println(arr);
}
}