排序算法5---快速排序

Posted 干货频道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法5---快速排序相关的知识,希望对你有一定的参考价值。

快速排序是一种比较排序,它采用了一种分治的策略,分治法的思想就是,将一个问题分解为规模更小但结构与原问题一样的子问题,解决每个子问题又和解决原问题一样,继续分解,这种问题一般用递归解决。

快速排序的基本思想就是:首先通过一种方式将一个序列分为两部分,其中一部分的所有元素都比另一部分的小,然后再分别对这两部分按照以上方法继续排序,直到所有数据有序。

那么以何种方法将一个序列分为两部分,其中一部分的所有元素都比另一部分的小呢?我们可以先从序列中选出一个基准数(选基准数的方法很多,可以是随机数、可以是中间元素、可以是第一个元素,本文以序列第一个元素为基准数),然后通过比较,将所有比基准数小的元素放到基准数左边,将所有比基准数大的元素放到基准数右边,这样就实现了上面的分解。

算法原理


从序列(数组)中取出第一个元素作为基准数;

从序列后面向前面搜索,找到第一个小于基准数的元素,从序列前面向后面搜索,找到第一个大于等于基准数的元素,交换这两个元素位置

重复第二步继续搜索,直到从后向前和从前向后碰到一起,将基准数放到这里,结束循环;

重复前三步,直到所有元素排好序。


算法分析

下面以数列 a[] =  {6,2,3,8,1,5,9,4,7} 为例,用直观的图像来演示快速排序过程。


说明:上面是以序列第一个元素为基准数,当然也可以选其他元素为基准数。另一方面,这里是先从右向左找小于基准数的元素,再从左向右找大于基准数的元素(注意先后顺序:先从右向左,再从左向右),然后交换两个元素。其实我们也可以每次找到相应元素后,就和基准数交换;或者使用所谓的“挖坑法”,请自行搜索了解。


算法实现


这里用递归实现快速排序,递归函数的编写一定要注意退出循环的条件,稍有不慎就会成为死循环。下面的快速排序函数参数与前面的排序算法有些不同,这里有3个参数: arr 是要排序的数组指针;left 是数组左边界,一般是数组下标 0; right 是数组右边界,一般是数组下标 n-1。例如:数组 a[N],进行快速排序 quick_sort(a, 0, N-1);


static void swap(int *a, int *b)

{

int val = 0;

val = *a;

*a = *b;

*b = val;

}


// 快速排序

void quick_sort(int *arr, int left, int right)

{

        int i = 0, j = 0;

int key = 0;


if(left > right)

return;

key = arr[left];

i = left;

j = right;

while(i < j)

{

while(i < j && arr[j] >= key)  // 先从右向左

j--;

while(i < j && arr[i] <= key)  // 再从左向右

i++;

swap(&arr[i], &arr[j]);

}

        swap(&arr[left], &arr[i]);

quick_sort(arr, left, i - 1);    // 递归,左边

quick_sort(arr, i + 1, right); // 递归,右边    

}


算法改进


上述快速排序中使用了递归,也就涉及多次的函数调用,我们知道函数调用的开销也是很大的,以此为切入点,提出优化方式。先进行快速排序,当分解的序列个数比较少时,采用其他排序算法(比如插入排序),这样就减少了大量的函数调用过程,效率也会提升一些。


算法性能


时间复杂度

快速排序的平均时间复杂度为o(n㏒n)


空间复杂度

快速排序的空间复杂度为 o(1)。因为只需要为两个元素交换位置时开辟一个空间,因此空间复杂度为o(1)。


稳定性

快速排序是一种不稳定的排序算法。

注意:上面的实现是不稳定的,但是快速排序的实现方法有多种,你也可以实现一个稳定的快速排序算法,因此分析一个排序算法的稳定性时,我们要看它的具体实现方法,切不能一概而论。


github源码连接:https://github.com/yqwung/sort



以上是关于排序算法5---快速排序的主要内容,如果未能解决你的问题,请参考以下文章

排序算法5--交换排序--快速排序

排序算法5---快速排序

六大排序算法:插入排序希尔排序选择排序冒泡排序堆排序快速排序

学习算法 -- 马桶排序冒泡排序和快速排序

经典排序算法——快速排序

小橙书阅读指南——快速排序和三向切分快速排序