快速排序
快速排序:
快排运用了分治的思想,分为三步:
- 分成子问题
- 递归处理子问题
- 子问题合并 其中核心思想是:选定一个数x,让待排数组中x左边的数均小于x,X右边的数均大于X,此时x会放在最终位置(该位置在最后不会改变)上,进行递归,缩小l和r之间的距离使得每一个数的左边一个数比它小,右边一个数比它大,即达到了排序的效果,代码如下。
void quick_sort(int q[], int l, int r)
{
//递归结束条件
if(l >= r) return;
int x = q[(l + r) >> 1];
int i = l - 1, j = r + 1;
while(i < j)
{
do i ++; while(q[i] < x);//会让i停在>=x的位置
do j --; while(q[j] > x);//会让j停在<=x的位置
if(i < j) swap(q[i], q[j]);
}
quick_sort(q, l, j);
quick_sort(q, j + 1, r);
}
例如:
快速排序的时间复杂度为: 稳定性:不稳定
第k个数
给定一个长度为n的整数数列,以及一个整数k,请用快速选择算法求出数列从小到大排序后的第k个数。
本体可以利用快排的性质,即在经过一趟排序后会确定选定的数的最终位置j,然后再判断K在j的左边还是右边,在左边就可以只递归左边,在右边就只需要递归右边。
int quick_sort(int q[], int l, int r, int k)
{
if(l >= r) return q[l];
int x = q[(r + l) >> 1], i = l - 1, j = 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]);
}
int s1 = j - l + 1;
//int s2 = r - j;
if(k <= s1) return quick_sort(q, l, j, k);
else return quick_sort(q, j + 1, r, k - s1);
}