赞
踩
【图解】快速排序—超级容易理解的做法
打算开始写算法专栏了,第一篇文章写什么呢?就快速排序吧!
快速排序的思想就是分治的思想,分治思想在算法中是非常常用也是非常重要的!一个问题,可以把它一分为二,然后再分别处理,依次类推,这就是分治的思想。
那么快速排序是怎么一回事呢?我来告诉你:
快速排序指的是,我们从一组数中任意选定一个数字(我们称这个数字叫基准值),然后经过一轮排序后使得小于基准值的数全部在基准值的左边;大于基准值的数全部在基准值的右边。这样我们从大的模块上来说就有序了,左边部分的最大值小于右边部分的最小值,然后再分别对左边部分快排,右边部分快排,直到有序
看完这段话是不是不太好理解呢?没关系,我来举个简单的例子:
有5个数字,分别是 3 1 2 4 5,利用快速排序将其变成升序序列
那么,首先我们来选取一个基准值,基准值是任意的,你可以选第一个数作为基准值,也可以选最后一个,也可以选择中间的数,都可以!看你心情喽,但是如果你使用我接下来这种做法,那么为了确保万无一失,我建议你选取中间的数!那怎么选取中间的数呢?我们利用数组长度除以2 是不是就得到中间数的下标了呢
//定义 l 为数组起始, r 为数组结尾 , 数组为 a[], 基准值为 x
int l = 0, r = a.size() - 1;
x = a[(l + r) / 2];
这样,基准值 x 就得到了,那么这里你也可以这样写
//我们知道,在 位运算中,右移一位就是除以2的意思,故可以使用右移
int l = 0 , r = a.size() - 1;
x = a[l + r >> 1];
现在,基准值找到了,在序列3 1 2 4 5
中,通过l + r >> 1
得到下标为2,故基准值x = a[2],即 数字2
此时,我们利用双指针 i, j 分别代表左边指针和右边指针
,分别从数组起始端和末尾段分别向中间移动,如果左边遇到大于2
的数停止左边指针移动;如果右边遇到小于2
的数,停止右边指针移动;此时如果i < j
那么将两个数交换swap(a[i], a[j])
,i指针和j指针
继续移动, 直到 i > j
,停止移动,此时第一轮结束。具体如下:
第一次比较,3 > 2
所以3应该是在右半边的,此时 i 指针
停止后移;j指针
所指向的 5 > 2
, j指针
前移
再次比较,j指针
所指向的 4 > 2
, j指针
继续前移
此时,j 指针
所指向的 2 ≯ 2
,故 j 指针
停止移动。判断 i< j ?
如果符合,交换a[i], a[j]
。如下
交换完成后,判断 I < j ?
符合条件,继续移动
i指针
指向的 1 < 2
, 故 i指针
继续移动
此时,i 指针
指向的 3 ≮ 2
,i指针
停止移动;j 指针
向前移动
j指针
指向的1 ≯ 2
,j指针
停止移动;判断i< j ?
不符合条件,第一轮结束
接下来开始分别递归左边和右边,左边的起始为 l = 0, r = j
; 右边的起始为 l = j + 1, r = r
对左边进行快排,选择基准值 x = l + r >> 1
, 即(0 + 1 ) / 2 = 0
, 所以a[0] = 2
i指针
指向的 2 ≮ 2
,故 i指针
停止移动;j指针
指向的1 ≯ 2
,故,j 指针
停止移动;此时i< j
, 交换a[i], a[j]
继续移动 i, j
。此时,发现i和j
指向的值均不满足条件,且j > i
,不符合交换和循环条件,结束
同理:右半边也是如此,故总的排序结果为
1. 快排的平均时间复杂度:O(nlogn)
2. 空间复杂度:O(logn)
3. 稳定性:由于此排序无法保证相等元素的相对位置不变,故它不是稳定的排序
#include <iostream> using namespace std; const int N = 100010; int q[N]; int n; //快速排序 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() { cin >> n; for (int i = 0; i < n; i ++) scanf("%d",&q[i]); quick_sort(q, 0, n - 1); for (int i = 0; i < n; i ++) printf("%d ",q[i]); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。