活动地址:CSDN21天学习挑战赛
一、快速排序算法
快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。
快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用,再加上快速排序思想----分治法也确实实用,因此很多软件公司的笔试面试,包括像腾讯,微软等知名IT公司都喜欢考这个,还有大大小的程序方面的考试如软考,考研中也常常出现快速排序的身影。
总的说来,要直接默写出快速排序还是有一定难度的,因为本人就自己的理解对快速排序作了下白话解释,希望对大家理解有帮助,达到快速排序,快速搞定。
1.基本思路
快速排序的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据比另一部分的所有数据要小,再按这种方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,使整个数据变成有序序列。
排序算法的思想非常简单,在待排序的数列中,我们首先要找一个数字作为基准数(这只是个专用名词)。为了方便,我们一般选择第 1 个数字作为基准数(其实选择第几个并没有关系)。接下来我们需要把这个待排序的数列中小于基准数的元素移动到待排序的数列的左边,把大于基准数的元素移动到待排序的数列的右边。这时,左右两个分区的元素就相对有序了;接着把两个分区的元素分别按照上面两种方法继续对每个分区找出基准数,然后移动,直到各个分区只有一个数时为止。
2.算法流程
1)输入
n个数的序列,通常直接存放在数组中,顺序不定
2)过程
- 先从数列中取出一个数作为基准数。
- 分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
- 再对左右区间重复第二步,直到各区间只有一个数。
动图演示如下:
3)输出
输入序列的一个新序列,满足从小到大的顺序
3.伪代码
快排中用到了递归,在编写代码时用function来声明定义一个函数名,进行调用
FUNCTION PARTITION(A,p,r)
x = A[r]
i = p - 1
for j = p to r - 1
if a[j] < x
i = i + 1
exchange A[i] with A[j]
exchange A[i + 1] with A[r]
return i + 1
partion函数只进行第一趟排序,要进行递归调用
FUNCTION QUICKSORT(A,p,r)
if p < r
q = PARTITION(A,p,r)
QUICKSORT(A,p,q-1)
QUICKSORT(A,q+1,r)
二、算法实现
1.基本算法实现
1)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);
}
}
2) 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[i] < arr[pivot]:
swap(arr, i, index)
index+=1
i+=1
swap(arr,pivot,index-1)
return index-1
def swap(arr, i, j):
arr[i], arr[j] = arr[j], arr[i]
2.时间性能分析
对于快速排序来说,由于无论如何划分,比较的次数都是固定的,不会超过O(n),故划分的次数是重点分析方面
1)最好的情况
如果每次待排序元素都恰好处在中间位置,将原有序列分成两个等长的子序列,每次划分都是这样的情况,总共划分的次数可以用O(log2n)(以2为底),时间复杂度为:O(nlog2n)
2)最坏的情况
快速排序在最坏情况下的时间复杂度和冒泡排序一样,是O(n^2)
3)平均情况
对于快速排序,是基于关键字比较得的内部排序算法中速度最快的,平均性能可以达到O(nlog2n)