• 微信号
  • 微信号
您当前的位置:首页 > 学海无涯 > 茑语花香>排序算法-快速排序

排序算法-快速排序

孤峰 孤峰家 2023-07-16 150人阅读

快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。

快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。

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

快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高!它是处理大数据最快的排序算法之一了。虽然 Worst Case 的时间复杂度达到了 O(n2),但是人家就是优秀,在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好,可是这是为什么呢,我也不知道。好在我的强迫症又犯了,查了 N 多资料终于在《算法艺术与信息学竞赛》上找到了满意的答案:

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

1. 算法步骤

从数列中挑出一个元素,称为 “基准”(pivot);

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

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

递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它较后的位置去。

2. 动图演示

3. JavaScript 代码实现

function quickSort(arr, left, right) { 

var len = arr.length,

partitionIndex,

left = typeof left != 'number' ? 0 : left,

right = typeof right != 'number' ? len - 1 : right;

if (left < right) {

partitionIndex = partition(arr, left, right);

quickSort(arr, left, partitionIndex-1);

quickSort(arr, partitionIndex+1, right);

}

return arr;

}

function partition(arr, left ,right) { // 分区操作

var pivot = left, // 设定基准值(pivot)

index = pivot + 1;

for (var i = index; i <= right; i++) {

if (arr < arr[pivot]) {

swap(arr, i, index);

index++;

}

}

swap(arr, pivot, index - 1);

return index-1;

}

function swap(arr, i, j) {

var temp = arr;

arr = arr[j];

arr[j] = temp;

}

function partition2(arr, low, high) {

let pivot = arr[low];

while (low < high) {

while (low < high && arr[high] > pivot) {

--high;

}

arr[low] = arr[high];

while (low < high && arr[low] <= pivot) {

++low;

}

arr[high] = arr[low];

}

arr[low] = pivot;

return low;

}

function quickSort2(arr, low, high) {

if (low < high) {

let pivot = partition2(arr, low, high);

quickSort2(arr, low, pivot - 1);

quickSort2(arr, pivot + 1, high);

}

return arr;

}

4. Python 代码实现

def quickSort(arr, left=None, right=None): 

left = 0 if not isinstance(left,(int, float)) else left

right = len(arr)-1 if not isinstance(right,(int, float)) else right

if left < right:

partitionIndex = partition(arr, left, right)

quickSort(arr, left, partitionIndex-1)

quickSort(arr, partitionIndex+1, right)

return arr

def partition(arr, left, right):

pivot = left

index = pivot+1

i = index

while i <= right:

if arr < arr[pivot]:

swap(arr, i, index)

index+=1

i+=1

swap(arr,pivot,index-1)

return index-1

def swap(arr, i, j):

arr, arr[j] = arr[j], arr

5. Go 代码实现

func quickSort(arr []int) []int { 

return _quickSort(arr, 0, len(arr)-1)

}

func _quickSort(arr []int, left, right int) []int {

if left < right {

partitionIndex := partition(arr, left, right)

_quickSort(arr, left, partitionIndex-1)

_quickSort(arr, partitionIndex+1, right)

}

return arr

}

func partition(arr []int, left, right int) int {

pivot := left

index := pivot + 1

for i := index; i <= right; i++ {

if arr < arr[pivot] {

swap(arr, i, index)

index += 1

}

}

swap(arr, pivot, index-1)

return index - 1

}

func swap(arr []int, i, j int) {

arr, arr[j] = arr[j], arr

}

6. C++版

//严蔚敏《数据结构》标准分割函数 

Paritition1(int A[], int low, int high) {

int pivot = A[low];

while (low < high) {

while (low < high && A[high] >= pivot) {

--high;

}

A[low] = A[high];

while (low < high && A[low] <= pivot) {

++low;

}

A[high] = A[low];

}

A[low] = pivot;

return low;

}

void QuickSort(int A[], int low, int high) //快排母函数

{

if (low < high) {

int pivot = Paritition1(A, low, high);

QuickSort(A, low, pivot - 1);

QuickSort(A, pivot + 1, high);

}

}

7. Java 代码实现

public class QuickSort implements IArraySort { 

@Override

public int[] sort(int[] sourceArray) throws Exception {

// 对 arr 进行拷贝,不改变参数内容

int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

return quickSort(arr, 0, arr.length - 1);

}

private int[] quickSort(int[] arr, int left, int right) {

if (left < right) {

int partitionIndex = partition(arr, left, right);

quickSort(arr, left, partitionIndex - 1);

quickSort(arr, partitionIndex + 1, right);

}

return arr;

}

private int partition(int[] arr, int left, int right) {

// 设定基准值(pivot)

int pivot = left;

int index = pivot + 1;

for (int i = index; i <= right; i++) {

if (arr < arr[pivot]) {

swap(arr, i, index);

index++;

}

}

swap(arr, pivot, index - 1);

return index - 1;

}

private void swap(int[] arr, int i, int j) {

int temp = arr;

arr = arr[j];

arr[j] = temp;

}

}

8. PHP 代码实现

function quickSort($arr) 

{

if (count($arr) <= 1)

return $arr;

$middle = $arr[0];

$leftArray = array();

$rightArray = array();

for ($i = 1; $i < count($arr); $i++) {

if ($arr[$i] > $middle)

$rightArray[] = $arr[$i];

else

$leftArray[] = $arr[$i];

}

$leftArray = quickSort($leftArray);

$leftArray[] = $middle;

$rightArray = quickSort($rightArray);

return array_merge($leftArray, $rightArray);

}

转载:感谢您阅览,转载请注明文章出处“来源从小爱孤峰知识网:一个分享知识和生活随笔记录的知识小站”。

链接:排序算法-快速排序http://www.gufeng7.com/niaolang/550.html

联系:如果侵犯了你的权益请来信告知我们删除。邮箱:119882116@qq.com