快速排序
来源:互联网 发布:python中文编码问题 编辑:程序博客网 时间:2024/05/01 17:20
快排
废话不说,先贴上代码,代码在《c程序设计语言》p74:
void swap(int v[],int i,int j){int temp;temp = v[i];v[i] = v[j];v[j] = temp;}void qsort(int v[],int left,int right){int i,last;void swap(int v[],int i,int j);if(left >= right)return;swap(v,left,(left + right)/2);last = left;for(i = left+1;i<=right;i++) if(v[i] < v[left])swap(v,++last,i);swap(v,left,last);qsort(v,left,last-1);qsort(v,last+1,right);}
假定初始给定:v[7]
01234567683259这里left = 0,right = 6①swap( v, left, ( left+right ) / 2 )
本例swap(v, 0 , 3),即将 首元素 ↔中间元素
01234563687259
②last = left
last = left = 0
③for(i = left + 1;i <= right;i++)
if ( v[i] < v[left])
swap(v, ++last, i)
本例:for( i = 1; i <= 6; i++),将数组v[7]从v[1]到v[6]扫描,
当满足条件:v[i] < v[left] = v [0] = 3,也就是,比首元素3还要小的话,
那么执行:swap(v,++last,i),执行的是交换元素的操作。
结合上面的实例,i = 1, v[1] = 6 > v[left] = 3,不执行交换操作;
i = 2, v[2] = 8 > v[left] = 3,不执行交换操作;
i = 3, v[3] = 7 > v[left] = 3,不执行交换操作;
i = 4, v[4] = 2 < v[left] = 3,满足if的条件,第一次执行swap操作,将v[4]与v[++last]交换,last之前为0,++执行完结果为last = 1,那么就是交换v[4]和v[1],结果:
01234563287659
i = 5, v[5] = 5 > v[left] = 3,不执行交换操作;
i = 6, v[6] = 9 > v[left] = 3,不执行交换操作;
那么这个for循环结束,只进行了1次swap交换,效果是将小于3的元
④swap(v ,left ,last)
swap(v , 0,1)交换v[0]和v[1]:
01234562387659⑤qsort(v , left,last - 1)
递归调用快排qsort,这时,qsort(v ,0,0),无需进行。
⑥qsort(v ,last+1,right)
qsort(v ,2 ,6),对v[2] ~ v[6]重复上述步骤,继续。
根据刚刚总结的,执行:
1. 首元素↔ 中间元素,这里left = 2 , right = 6
01234562367859
2. last = left = 2
3. for循环,操作的目的是:
范围:v[3] ~ v[6]
条件:小于v[left] = 6
操作:v[i] ↔ v[++last]
在v[3] ~ v[6]里,只有v[5]比v[left]小,所以只要swap一次即可,同时last = 3,v[5] ↔ v[3],。
01234562365879
4.swap(v, 2, 3)
01234562356879
5.qsort(v, 2, 2)
因为for循环里,也只执行了一次swap操作,故这一步不需要操作,已经有序。
6.qsort(v, 4, 6)
012345623568796.1 首元素 ↔ 中间元素,left = 4, right = 601234562356789
6.2 last = left = 4
6.3 for循环:
范围:v[4] ~ v[6]
条件:小于v[left] = 7
操作:v[i] ↔ v[++last]
发现,没有比v[left] = 7还小的数,所以不执行操作。不过此时,我们发现,顺序好像已经排好了。当然接下来的操作也没有意义了。
总结
通观整个算法思想,利用了递归,减少了代码量,不过理解起来也稍加费力。打完上面的例子,才发现不好,因为每次for循环之多只执行了一次,没有完全展现出“分治”的思想来。不妨再来一个,简单说明一下。
初始:left = 0, right = 6
step1. 将中间元素与首元素交换,即把a[3] = 6选为key,放到首位。同时将last 赋值为left的值,last = 0.因为left不能随意改变,last可以记录交换的位置。
01234566478329
step2. for循环:
范围:v[1] ~ v[6]
条件:小于v[0] = 6
操作:交换v[i]↔ v[++last]
i = 1, v[1] = 4 < v[0] = 6,++last = 1 ,v[1] ↔ v[1],不需要交换。
i = 2, v[2] = 7 > v[0] = 6,无需操作。
i = 3, v[3] = 8 > v[0] = 6,无需操作。
i = 4, v[4] = 3 < v[0] = 6,++last = 2 ,v[4] ↔ v[2]。
01234566438729
i = 5, v[5] = 2 < v[0] = 6,++last = 3 ,v[5] ↔ v[3]。
01234566432789
i = 6, v[6] = 9 > v[0] = 6,无需操作。
可以看到for循环的效果是:将比6小的数依次从1开始排,而last记录了最后一个比6小的数。
step3. 将v[left] ↔ v[last]
01234562436789可以看到,6作为key,在6的前面是比6小的数,6的后面是比6大的数。
step4. qsort(v, left, last - 1)
qsort(v, last + 1, right)
递归再次快排,将之前划分的两个子集再次排序,即v[0] ~ v[2] ,v[4] ~ v[6],只要两个子集顺序排好,自然连在一起是有序的。
当left >= right时候,即数组包含的元素的个数少于两个的时候,那么就意味着不能再划分了,已经有序了,不执行操作,return即可。
- 快速排序
- 快速排序
- 快速排序
- 快速排序!
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- HttpURLConnection重定向,获取及设置cookie
- 安装svn for myeclipse插件的时候提示“Failed to load JavaHL Library.”
- Remove Duplicates from Sorted List
- shell for循环用法总结
- Python变量函数:函数名存在变量中
- 快速排序
- NameValueCollection集合
- Hbase的SQL接口之Phoenix使用总结(1)
- spoj1182
- 1019、最大乘积连续子串解析
- 睡眠关机脚本
- 日志操作实现思路
- C#用什么方法可以减少或不使用switch
- PKU ACM/ICPC竞赛队最近八年比赛成绩