查看: 3143| 回复: 2
跳转到指定楼层
上一主题 下一主题
收起左侧

[二分/排序/搜索] 【七类排序】之第三种:选择排序

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
本帖最后由 北美农民 于 2013-1-6 09:50 编辑

注:若无特殊说明, 排序以递增为目的。

选择排序(Select Sort)思想和插入排序(Insertion Sort)接近。

令长度为n的数组a[0..n-1]。

选择排序则是将无序区a[i..n-1]中的最小值a[k]插入有序区a[0..i-1]的末位使得a[0..i]成为有序区。
还记得之前的插入排序么, 重温一下, 其思想是:将a[ i ]并入有序区a[0..i-1]使得a[0..i]]成为有序区。

实现非常简单, 每一次遍历记录最小值的位置, 然后与a[ i ]交换即可。
程序核心部分代码为:

for (int i=0; i<n; i++) {
    int flag=i;
    for (int j=i+1; j<n; j++)
         if (a[ j ]<a[ flag ])
             flag = j;

     swap(a[ i ], a[ flag ])
}

就这么直接能写出, 我也想不到什么优化了, 各位有啥ideas的欢迎提出来。

就这样没了好像比较水, 再写一点关于swap函数的东西。
这里, 笔者默认各位懂得指针,形参等概念。
一般来说, swap函数是通过中间变量实现的,推荐的常规写法为:

void swap(int &p, int &q) {
        int temp = p;
        p=q;
        q=temp;
}



然而, 若面试官不允许用中间变量怎么办? 介绍两种方式。

第一种:


p^=q;
q^=p;
p^=q;

点评:这是经典的异或位运算方式, 不需要中间变量即可完成交换, 但是有一点问题就是, 若p和q指向的是同一个指针那么结果会导致p和q置零。 若在选择排序算法中的某次遍历中, flag等于i, 那么执行swap(a[flag], a)则会出现问题,而且很难发现,最严重的情况就是数组原来就有序,那么每次置换都失败。

所以在原函数的基础上加一层判断:
if (p!=q){
  p^=q;
  q^=p;
  p^=q;

}


第二种:

p=p+q;
q=p-q;
p=p-q;

点评: 很容易理解, but very impressive....

上一篇:【七类排序】之第二种:插入排序
下一篇:【七类排序】之第四种:快速排序
🔗
xue777hua 2012-11-29 10:40:11 | 只看该作者
全局:
根据KISS原则,交换还是带一个中间变量吧,代码可读性好。
回复

使用道具 举报

🔗
Toby 2013-1-6 09:36:32 | 只看该作者
全局:
第一个代码最后一行有小错哦,应是 swap(a[ i ], a[ flag ])

点评

谢谢,已改  发表于 2013-1-6 09:50
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表