快速排序
算法思想: 快速排序采用的是分治思想,即在一个无序的序列中选取一个任意的基准元素pivot,利用pivot将待排序的序列分成两部分,前面部分元素均小于或等于基准元素,后面部分均大于或等于基准元素,然后采用递归的方法分别对前后两部分重复上述操作,直到将无序序列排列成有序序列。(by百度百科~)
快速排序代码如下,主函数中主要是函数调用和准备待排序的序列,算法主体在quick_sort函数中
#include<iostream>
using namespace std;
const int N = 10010;
int q[N], n;
//快速排序,平均时间复杂度为O(nlong),最坏情况下时间复杂度为O(n^2)
void quick_sort(int q[], int l, int r)
{
if (l >= r) return ;
int i = l-1, j = r+1, x = q[(l+r) >> 1];
while(i < j)
{
do i++ ;while(q[i]<x);
do j-- ; while(q[j] > x);
if (i < j) swap(q[i], q[j]);
}
// 可根据题目需求来判断是否只需要排序某一部分可以优化算法的时间复杂度
quick_sort(q, l, j);
quick_sort(q, j+1, r);
}
int main()
{
scanf("%d", &n);
//输入待排序数组
for(int i = 0;i < n; i++) scanf("%d", &q[i]);
// 准备参数
int l = 0, r = n-1;
//调用快排函数
quick_sort(q, l, r);
return 0;
}
我们希望结果是一个有序的序列(默认是顺序,从小到大),这里我们定义了两个指针i 和j用来遍历数组,假设数组是有序的,则我们每次遍历的时候q[i] 一定是小于x的而q[j] 一定是大于x的,如果遇到了q[i]大于x或者q[j] 小于x 则表明该处一定是乱序的,所以我们要做的事情就是交换这两个位置的值,当然,我们的i一定是小于j的。然后我们分别对以基准值分出来的左右两个数组进行递归,最终可以得到一个有序的序列。
在某些情况下我们只需要排序半边或者需要有选择的对某半边进行排序,我们就可以在递归的时候进行判断,符合我们需要的条件我们再递归,这样可以减小计算量,优化时间复杂度。