1、概述
快速排序是对冒泡算法的一种改进。
快序排序的思想与归并排序类似,都是采用分而治之的方式进行排序,其基本思想是通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的数据都比另一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过车过可以递归进行,直到整个数据有序。
2、算法原理
基本原理:取出无序数列中的第一个值,然后通过比较将比该值小的元素放到该值的前方,将比该值大的元素放到该值的后方,然后分别再对前半部和后半部进行上述操作。
步骤:
1)从数列中跳出一个元素,作为 基准pivot
2)重新排序数列,所有比基准小的放在基准前,所有比基准大的放在基准后(相同的数可以任意一边)在这个分区退出后,该基准就处于数列的中间位置,称为分区partition操作
3)递归recursive的把小于基准值的子数列和大于基准值的子数列排序
一趟快速排序的步骤:
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
2)以第一个数组元素作为基准数据,赋值给point,即point=A[0];
3)从j开始向前搜索,即由后开始向前搜索(j减1),找到第一个小于point的值A[j],将A[j]和A[i]互换;
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于point的A[i],将A[i]和A[j]互换;
5)重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,
使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。
另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。
3、举例
对 [5, 7 ,1, 8, 4]进行快排
1)选中基准 point = 5,将比5小的放在5之前,比5大的放在5之后,low负责遍历前半部分,将前部分大于5的放后面,high负责遍历后半部分,将后部分小于5的放前面,以下是一趟快排的示意图
2)需要对point两边的数组分别在进行快排,知道整个数组有序为止
4、算法实现
func quickSort(_ array : inout [Int], _ low : Int, _ high : Int){
if low >= high {
return
}
var i = low
var j = high
//基准值
let point = array[i]
while i<j {
//从右边开始找,要是找到右边有比point小的,交换他们的位置
//下面的循环,当找到array[i]<point时结束
while i<j && array[j]>=point{
j -= 1
}
//循环结束,也就是找到array[j]<point,交换他们的位置
array[i] = array[j]
//2 从左开始找,此时是i增加,当找到array[i]>point时交换他们的位置
while i<j && array[i]<=point{
i += 1
}
array[j] = array[i]
}
//每一次排序比较完成后基准数的位置,按这个位置切分数组
array[i] = point
//递归处理基准左右的子数列
quickSort(&array, low, i-1)
quickSort(&array, i+1, high)
}
调用:
var array6 = [5, 7, 1, 8, 4]
quickSort(&array6, 0, array6.count-1)
print(array6,"\n")
运行结果:
[1, 4, 5, 7, 8]
5、时间复杂度
快排的时间复杂度为时间复杂度 O(nlogn)
注:排序的具体实现代码在 SortSummary.swift 文件里 调用是在 ViewController.swift