排序算法之冒泡排序与选择排序
2012-12-01 16:12
141 查看
之前在ACM机房呆了很长的一段时间,对算法还是了解一些的,只不过现在暂时没有在接触它了,忘记了许多。可是,还有一句话:“瘦死的骆驼比马大”,即使有再长的时间没学习,但基础依然在那儿,看一段时间还是能够很熟练地使用的。
前几天做了一个笔试题,最后一题就是排序题,给出7、8个整数让排序,不限排序的算法。于是我就用了冒泡排序,结果到面试的时候,面试官问我为什么不用更高级的排序算法呢,比如快排。好吧,我当时确实是无言以对,我还能说些什么呢,难道我要说:“我会使用快排,就是没写,要不我现在写给你看”。当时我是怎么想的呢,反正他又没限制排序的算法,而且写快排时可能在细节上会出错,关键是排序的数据量还很小,于是就打算用冒泡了。结果就这样悲剧了,有人说了这么一句话,感觉挺在理的,“你用什么样的排序算法,就代表了你什么样的水平;既然你用了冒泡排序,也就代表你的水平是在冒泡的水平”。
吸取教训吧,以后要多出个心眼。
/*
忽然想起个事,每次的面试后,都会发现自己学的东西很少很少,要学的东西还有很多,可是就是不知道怎么入手,算法得会吧,js前台技术得会吧,数据库操作得会吧,数据库配置和优化、面向对象的编程、linux下的服务器配置得会吧,而且数据库还不能只精通一种,至少得两种,比如:MySQL, NoSQL, Oracle,等等;得要熟悉模板吧、得要熟悉框架吧、得会二次开发吧,会部署网站的代码吧、得有拿的出手的作品吧,除了PHP还得会点其他的语言吧;好的,到现在,把该学的都已经学过一遍了,总得有项目经验吧;没项目经验?在一个好的学校也是可以找个工作的;如果不是重点学校呢,呃?!这个!
*/
那天面试可想而知没有很理想,于是打算回来看看数据结构,看看排序算法、树、图。今天就先总结一下冒泡排序吧。
我写的简单的排序算法主要解决的有3种要排序的格式:1,以数字为下标的一维数组;2,二维数组,第二维的下标是数字,第一维的下标任意,以第一维数组为单位进行排序;3,二维数组,对值全部进行排序。
//我也不知道该用什么语言来写,其实不管什么语言,思想是一样的,只不过对于不同的语言,有着不同的语法规则而已。那我就用PHP写吧。
冒泡排序的思想大家应该都是了解的,毕竟接触的第一个排序算法就是冒泡排序了。
这里要说一下双向冒泡排序。双向冒泡排序的原理与冒泡排序的原理是一样的,只不过冒泡排序每经过一趟排序后,都会从头的下一个数开始;而双向冒泡排序则是一趟排序完成之后再反着排序回去,然后再回来。比如第一趟排序是大数下沉,那么第二趟排序就是从倒数第二个数开始向回走、小数上浮,第三趟排序从第三个数开始又是大数下沉,直到第n-1趟排序完成。
当然还有就是对二维数组的排序。这种情况是按数组为单位进行排序的,比如有个学生数组$student,$student的每个元素就是一个学生,学生自己有很多的特性,比如name, sex, score等等。于是我们就可以创建这样一个二维数组$student = array(array('name'=>'liming', 'sex'=>'male' score=>89), array('name'=>'xiaohong', 'sex'=>'female' score=>91), array('name'=>'xiaoli', 'sex'=>'male' score=>78), array('name'=>'keke', 'sex'=>'female' score=>60))。
我们希望按学生的某个特性(比如分数)来进行排序,但是每个学生自己的特性不能乱。我们可以这样写代码。
这样我们就完成了对学生按成绩进行排序。
现在我们来讨论下选择排序,讨论的思路和冒泡排序是一样的,这里就直接上代码了。
View Code
冒泡和选择就先到这里吧,可能还有很多不足的地方。下次讲插入排序-直接插入排序和二分插入排序。
前几天做了一个笔试题,最后一题就是排序题,给出7、8个整数让排序,不限排序的算法。于是我就用了冒泡排序,结果到面试的时候,面试官问我为什么不用更高级的排序算法呢,比如快排。好吧,我当时确实是无言以对,我还能说些什么呢,难道我要说:“我会使用快排,就是没写,要不我现在写给你看”。当时我是怎么想的呢,反正他又没限制排序的算法,而且写快排时可能在细节上会出错,关键是排序的数据量还很小,于是就打算用冒泡了。结果就这样悲剧了,有人说了这么一句话,感觉挺在理的,“你用什么样的排序算法,就代表了你什么样的水平;既然你用了冒泡排序,也就代表你的水平是在冒泡的水平”。
吸取教训吧,以后要多出个心眼。
/*
忽然想起个事,每次的面试后,都会发现自己学的东西很少很少,要学的东西还有很多,可是就是不知道怎么入手,算法得会吧,js前台技术得会吧,数据库操作得会吧,数据库配置和优化、面向对象的编程、linux下的服务器配置得会吧,而且数据库还不能只精通一种,至少得两种,比如:MySQL, NoSQL, Oracle,等等;得要熟悉模板吧、得要熟悉框架吧、得会二次开发吧,会部署网站的代码吧、得有拿的出手的作品吧,除了PHP还得会点其他的语言吧;好的,到现在,把该学的都已经学过一遍了,总得有项目经验吧;没项目经验?在一个好的学校也是可以找个工作的;如果不是重点学校呢,呃?!这个!
*/
那天面试可想而知没有很理想,于是打算回来看看数据结构,看看排序算法、树、图。今天就先总结一下冒泡排序吧。
我写的简单的排序算法主要解决的有3种要排序的格式:1,以数字为下标的一维数组;2,二维数组,第二维的下标是数字,第一维的下标任意,以第一维数组为单位进行排序;3,二维数组,对值全部进行排序。
//我也不知道该用什么语言来写,其实不管什么语言,思想是一样的,只不过对于不同的语言,有着不同的语法规则而已。那我就用PHP写吧。
冒泡排序的思想大家应该都是了解的,毕竟接触的第一个排序算法就是冒泡排序了。
<?php $arr = array(12, 234, 33, 23, 1, 54, 0); function maopao(&$a){ $t = count($a); for($i=0; $i<$t-1; $i++){ for($j=0; $j<$t-1-$i; $j++){ if($a[$j]>$a[$j+1]){ $temp = $a[$j]; $a[$j] = $a[$j+1]; $a[$j+1] = $temp; } } } } print_r($arr); maopao($arr); echo "<br/>"; print_r($arr); ?>
这里要说一下双向冒泡排序。双向冒泡排序的原理与冒泡排序的原理是一样的,只不过冒泡排序每经过一趟排序后,都会从头的下一个数开始;而双向冒泡排序则是一趟排序完成之后再反着排序回去,然后再回来。比如第一趟排序是大数下沉,那么第二趟排序就是从倒数第二个数开始向回走、小数上浮,第三趟排序从第三个数开始又是大数下沉,直到第n-1趟排序完成。
<?php //双向冒泡排序 function maopao2(&$a){ $t = count($a); $low = 0; $high = $t-1; while($low < $high){ //正向冒泡,大数下沉 for($i=$low; $i<$high; $i++){ if($a[$i]>$a[$i+1]){ $temp = $a[$i]; $a[$i] = $a[$i+1]; $a[$i+1] = $temp; } } $high--; //反向冒泡,小数上浮 for($i=$high; $i>$low; $i--){ if($a[$i]<$a[$i-1]){ $temp = $a[$i]; $a[$i] = $a[$i-1]; $a[$i-1] = $temp; } } $low++; } } ?>
当然还有就是对二维数组的排序。这种情况是按数组为单位进行排序的,比如有个学生数组$student,$student的每个元素就是一个学生,学生自己有很多的特性,比如name, sex, score等等。于是我们就可以创建这样一个二维数组$student = array(array('name'=>'liming', 'sex'=>'male' score=>89), array('name'=>'xiaohong', 'sex'=>'female' score=>91), array('name'=>'xiaoli', 'sex'=>'male' score=>78), array('name'=>'keke', 'sex'=>'female' score=>60))。
我们希望按学生的某个特性(比如分数)来进行排序,但是每个学生自己的特性不能乱。我们可以这样写代码。
<?php function maopao3(&$a, $key){ $t = count($a); for($i=0; $i<$t-1; $i++){ for($j=0; $j<$t-1-$i; $j++){ if($a[$j][$key]>$a[$j+1][$key]){ $temp = $a[$j]; $a[$j] = $a[$j+1]; $a[$j+1] = $temp; } } } } maopao3($student, 'score'); ?>
这样我们就完成了对学生按成绩进行排序。
现在我们来讨论下选择排序,讨论的思路和冒泡排序是一样的,这里就直接上代码了。
View Code
<?php $arr = array(12, 234, 33, 23, 1, 54, 0); $ar = array( array('name'=>'liming', 'sex'=>'male', 'score'=>90), array('name'=>'asd', 'sex'=>'male', 'score'=>89), array('name'=>'bdf', 'sex'=>'female', 'score'=>92), array('name'=>'rgeg', 'sex'=>'male', 'score'=>60) ); //交换两个数 function swap(&$x, &$y){ $temp = $x; $x = $y; $y = $temp; } //选择排序 function xuanze1(&$a){ $t = count($a); for($i=0; $i<$t-1; $i++){ $k = $i; for($j=$i+1; $j<$t; $j++){ if($a[$j]<$a[$k]){ $k = $j; } } if($k != $i){ swap($a[$i], $a[$k]); } } } //双向选择排序 function xuanze2(&$a){ $t = count($a); $low = 0; $high = $t-1; while($low < $high){ print_r($a); echo "<br/>"; $min = $low; $max = $high; for($i=$low; $i<=$high; $i++){ if($a[$i]>$a[$max]){ $max = $i; }else if($a[$i]<$a[$min]){ $min = $i; } } if($min != $low){ swap($a[$low], $a[$min]); } if($min==$high && $max==$low){ //当最小数出现在最右端,同时最大数出现在最左端,会出现交换两次的情况 } else if($max!=$high){ swap($a[$high], $a[$max]); } $low++; $high--; } } //二维数组选择 function xuanze3(&$a, $key){ $t = count($a); for($i=0; $i<$t-1; $i++){ $k = $i; for($j=$i+1; $j<$t; $j++){ if($a[$j][$key] < $a[$k][$key]){ $k = $j; } } if($k != $i){ swap($a[$k], $a[$i]); } } } ?>
冒泡和选择就先到这里吧,可能还有很多不足的地方。下次讲插入排序-直接插入排序和二分插入排序。
相关文章推荐
- 插入排序,选择排序,冒泡排序等常用排序算法(java实现)
- C#的四种排序算法:冒泡排序、选择排序、插入排序和希尔排序
- 三种数组排序算法(冒泡排序、选择排序、插入排序、二分查找法)
- 几种常见的排序算法,选择排序,冒泡排序,希尔排序,堆排序,快速排序,归并排序,基数排序的比较
- 排序算法汇总(选择排序 ,直接插入排序,冒泡排序,希尔排序,快速排序,堆排序)
- 三种基础排序算法(选择排序、插入排序、冒泡排序)
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 蛮力法在排序算法中的应用(JAVA)--选择排序、冒泡排序
- 排序算法(一):插入排序、冒泡排序、合并排序、选择排序
- 基础排序算法(冒泡排序、选择排序、插入排序)
- 排序算法之插入排序、冒泡排序和选择排序
- 算法_基本排序算法之冒泡排序,选择排序,插入排序和希尔排序
- 排序算法-----冒泡排序和选择排序
- 排序算法之冒泡排序、选择排序、直接插入排序(java实现)
- 几种常用的排序算法:插入排序、冒泡排序、选择排序的算法及C++实现
- 黑马程序员----Java中几种常用排序算法(选择排序、冒泡排序、快速排序)
- 各种排序算法总结----基数排序、归并排序、插入排序、冒泡排序、选择排序、快速排序、堆排序、希尔排序
- 常用排序工具类:标准【正序、倒序】排序算法‘冒泡排序,选择排序,快速排序’
- C语言常用的几种排序算法代码(选择排序,冒泡排序,插入排序,快速排序)
- 三种基本排序算法-冒泡排序,选择排序,插入排序