排序算法之快速排序

时间:2024-03-15 08:30:45

快速排序,简称快排。也利用了分治思想。

快速排序是这样的:

如果要排序数组中下标从p到r之间的一组数据,我们选择p到r之间的任意一个数据作为pivot(分区点)。我们遍历p到r之间的数据,将小于pivot的放到左边,将大于pivot的放到右边,将pivot放到中间。
根据分治、递归的处理思想,我们可以用递归排序下标从p到q-1之间的数据和下标从q+1到r之间的数据,直到区间缩小为1,就说明所有数据都有序了。

递推公式:

递推公式:
quick_sort(p...r) = quick_sort(p...q-1) + quick_sort(q+1,r)

终止条件:
p >= r

将递推公式转化为代码:

//快速排序,A是数组,n表示数组的大小
quick_sort(A,n){
	quick_sort_c(A,0,n-1)
}

//快速排序递归函数,p,r为下标
quick_sort_c(A,p,r){
	if p>=r then return 

	q=partition(A,p,q-1)  //获取分区点
	quick_sort_c(A,p,q-1)
	quick_sort_c(A,q+1,r)
}

这里涉及一个partition()分区函数。而它的作用就是:随机选择一个元素作为pivot,然后对A[p…r]分区,函数返回pivot的下标。

partition(A,p,r){
	pivot := A[r]
	i := p
	for j:=p to r-1 do {
		if A[j] < pivot {
			swap A[i] with A[j]
			i := i+1
		}
	}
	swap A[i] with A[r]
	return i
}

我们通过游标 i 把 A[p…r-1] 分成两部分。其中 i 左边表示已经处理的,其中 j 表示一种遍历,从 i 开始往右一次与 pivot 比较,如果小于 pivot,那么,就把元素换到 i 的位置,同时 i 加1。最后,返回 i 的值作为分区点, i 左边的小于它,右边的大于它。

此分区函数的思路:i和j都从第一个元素开始,用 j 依次与pivot比较,如果比pivot小,则把它放到i的左边,同时 i 右移 ,j 也右移;最后把pivot和 i 位置的元素交换

分区示例图如下
排序算法之快速排序