qsort代码解析

78 篇文章 4 订阅
36 篇文章 0 订阅

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)
参考:《The C Programming language The Second Edition》

最近看The C Programming language 这本书,看到里面qsort的代码;
这次感受又不太一样,觉得里面qsort实现的很优雅;

void qsort(char *v[], int left, int right){
  int i, last;
  void swap(char *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(strcmp(v[i], v[left]) < 0)
      swap(v, ++last, i);
  swap(v, left, last);
  qsort(v, left, last - 1);
  qsort(v, last+1, right);
}

这份代码,觉得整个实现很完整又很简洁:
从输入鉴权,到比较flag选取,然后不断小值换位,接着flag换位到排序两边中间,最后两边各自递归处理;

1-输入鉴权:
排除掉异常值right < left, 排除掉只有一个值的情况right==left

2- 比较flag选取
选取中间位置值作为flag比较项,swap放在数组array[0],这样可以避免已排序数据效率很低情况;

3- 比较小值换位
把与flag值比较,较小的项,换位到flag后边,一个接一个的放置;
last最是指向<=flag的数字,从一开始指向flag-array[0],慢慢向后指向,总是指向最后一个<=flag的数字。

4- flag换位到排序值中间
经过比较换位后,flag后面:last指向一边是比flag小于等于的,last指向一边是大于flag的;
flag 和 小于它位置最靠后的last 两者交换一下;
这样,交换后flag就位于了 比它小于等于的后边,大于它的前边;
flag的位置后续就不需要变动了,位置确定好了;
flag的位置就选取结束了,之后也不会移动了。

5- 两边各自递归处理
flag位置选完毕后:比它小的一边递归进行下次的排序;比它大的一遍也递归进行下次的排序;
这次的话,新的两个排序的数量从数学统计上:
可以认为大致各一半的数据,数据量减少一半,排序的难度减少不止一半;
下一次flag位置选取复杂读降低一半;
递归下去,效率就比较高了。

基于数据模型统计上来看:
相比而言,冒泡排序与选择排序:第一个位置值选取n次比较,第二个位置值选取n-1次比较,第三个位置值选取n-2,…;
而qsort递归选取:第一层1个flag位置值选取n次比较,第二层两个flag位置值选取n/2次比较,第三层4个flag位置值选取n/2/2次比较…;
所以,时间复复杂度上比较来看,qsort效率是比较高的。

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春夜喜雨

稀罕你的喜欢!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值