十大经典排序算法(六、快速排序)

动图演示

快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。

快速排序的最坏运行情况是 O(n²),比如说顺序数列的快排。但它的平摊期望时间是 O(nlogn),且 O(nlogn) 记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn) 的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。

算法步骤

  1. 从数列中挑出一个元素,称为 "基准"(pivot);

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

  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

JavaScript

 1 function quickSort(arr, left, right) {
 2     var len = arr.length,
 3         partitionIndex,
 4         left = typeof left != 'number' ? 0 : left,
 5         right = typeof right != 'number' ? len - 1 : right;
 6 
 7     if (left < right) {
 8         partitionIndex = partition(arr, left, right);
 9         quickSort(arr, left, partitionIndex-1);
10         quickSort(arr, partitionIndex+1, right);
11     }
12     return arr;
13 }
14 
15 function partition(arr, left ,right) {     // 分区操作
16     var pivot = left,                      // 设定基准值(pivot)
17         index = pivot + 1;
18     for (var i = index; i <= right; i++) {
19         if (arr[i] < arr[pivot]) {
20             swap(arr, i, index);
21             index++;
22         }        
23     }
24     swap(arr, pivot, index - 1);
25     return index-1;
26 }
27 
28 function swap(arr, i, j) {
29     var temp = arr[i];
30     arr[i] = arr[j];
31     arr[j] = temp;
32 }
33 function partition2(arr, low, high) {
34   let pivot = arr[low];
35   while (low < high) {
36     while (low < high && arr[high] > pivot) {
37       --high;
38     }
39     arr[low] = arr[high];
40     while (low < high && arr[low] <= pivot) {
41       ++low;
42     }
43     arr[high] = arr[low];
44   }
45   arr[low] = pivot;
46   return low;
47 }
48 
49 function quickSort2(arr, low, high) {
50   if (low < high) {
51     let pivot = partition2(arr, low, high);
52     quickSort2(arr, low, pivot - 1);
53     quickSort2(arr, pivot + 1, high);
54   }
55   return arr;
56 }

Python

 1 def quickSort(arr, left=None, right=None):
 2     left = 0 if not isinstance(left,(int, float)) else left
 3     right = len(arr)-1 if not isinstance(right,(int, float)) else right
 4     if left < right:
 5         partitionIndex = partition(arr, left, right)
 6         quickSort(arr, left, partitionIndex-1)
 7         quickSort(arr, partitionIndex+1, right)
 8     return arr
 9 
10 def partition(arr, left, right):
11     pivot = left
12     index = pivot+1
13     i = index
14     while  i <= right:
15         if arr[i] < arr[pivot]:
16             swap(arr, i, index)
17             index+=1
18         i+=1
19     swap(arr,pivot,index-1)
20     return index-1
21 
22 def swap(arr, i, j):
23     arr[i], arr[j] = arr[j], arr[i]

C语言

 1 void swap(int *x, int *y) {
 2     int t = *x;
 3     *x = *y;
 4     *y = t;
 5 }
 6 
 7 void quick_sort_recursive(int arr[], int start, int end) {
 8     if (start >= end)
 9         return;
10     int mid = arr[end];
11     int left = start, right = end - 1;
12     while (left < right) {
13         while (arr[left] < mid && left < right)
14             left++;
15         while (arr[right] >= mid && left < right)
16             right--;
17         swap(&arr[left], &arr[right]);
18     }
19     if (arr[left] >= arr[end])
20         swap(&arr[left], &arr[end]);
21     else
22         left++;
23     if (left)
24         quick_sort_recursive(arr, start, left - 1);
25     quick_sort_recursive(arr, left + 1, end);
26 }
27 
28 void quick_sort(int arr[], int len) {
29     quick_sort_recursive(arr, 0, len - 1);
30 }

C++

 1 template <typename T>
 2 void quick_sort_recursive(T arr[], int start, int end) {
 3     if (start >= end)
 4         return;
 5     T mid = arr[end];
 6     int left = start, right = end - 1;
 7     while (left < right) { //在整个范围内搜寻比枢纽元值小或大的元素,然后将左侧元素与右侧元素交换
 8         while (arr[left] < mid && left < right) //试图在左侧找到一个比枢纽元更大的元素
 9             left++;
10         while (arr[right] >= mid && left < right) //试图在右侧找到一个比枢纽元更小的元素
11             right--;
12         std::swap(arr[left], arr[right]); //交换元素
13     }
14     if (arr[left] >= arr[end])
15         std::swap(arr[left], arr[end]);
16     else
17         left++;
18     quick_sort_recursive(arr, start, left - 1);
19     quick_sort_recursive(arr, left + 1, end);
20 }
21 template <typename T> //整數或浮點數皆可使用,若要使用物件(class)時必須設定"小於"(<)、"大於"(>)、"不小於"(>=)的運算子功能
22 void quick_sort(T arr[], int len) {
23     quick_sort_recursive(arr, 0, len - 1);
24 }

 

posted @ 2020-12-29 11:55  梓涵VV  阅读(136)  评论(0编辑  收藏  举报