关于排序,其实不论是哪一种语言,都有它内置的排序函数,咱们要用的时候调用就好了,既然如此,咱们为何还要讲这个东西呢?我想,其实,咱们讲排序更可能是在于排序中包含的思想算法,由于,算法对于计算机来讲至关重要,一个好的算法可以让计算机的效率达到事半功倍的效果,因此,算法是计算机语言中一门至关热门的课程,它所表明的计算机思惟也是很值得咱们去深刻研究的。javascript
我也知道,关于我标题中的排序,博客园中的不少做者都写过详细解释的文章,可能,笔者本人认为本身的理解更能体现出这个排序的工做原理吧,因此,笔者也就大惭不愧的在这里再次写下关于冒泡排序的文章,有须要的读者能够看一下。css
再进入正题以前,我给你们介绍一下谷歌浏览器一个颇有用的调试程序代码的功能,若是你已经知道,请略过。html
首先,打开谷歌浏览器,输入咱们的代码脚本:java
右键,点击检查,算法
按顺序点击,获取脚本的运行代码:数组
个人脚本是bubble.html,存储在www.test.com域名下面的js/f目录下面,每一个人的脚本不同,存储的目录也不同,请根据本身的状况来。浏览器
调出脚本的内容后,下面就是调试代码了。函数
选择好了断点以后,接下来在谷歌浏览器中再次运行脚本,就是对下面的www.test.com/js/f/bubble.html再回车运行测试
再次运行以后,你会看到这样的东西:优化
看到上面的那个蓝色矩形框了吗?这个蓝色矩形框就是脚本正在运行的代码位置,那咱们怎么让脚本的代码一步步的运行呢?
这里之因此对这个脚本的for循环代码进行断点监控,其实,我是为了查看冒泡排序究竟是怎么循环操做的,对于新手来讲,这样子直观的查看冒泡排序代码的运行状况会更好的了解算法的执行过程。
对于这个调试小功能就介绍到这里了,下面进入正题,没办法直接想象出冒泡排序的执行状况的话,你能够按我上面的步骤调出谷歌的调试功能,直观的查看冒泡排序的整个过程。
介绍一下两个变量互相调换的思惟,咱们借助中间变量来调换:
//交互元素,这里的代码是从脚本中截取出来的,这么简单,应该不影响理解 if(arr[j] > arr[j+1]){ mark = false; var temp = arr[j];//temp是中间变量,把要交换的第一个元素arr[j]赋值给中间变量,也是把第一个元素存储起来 arr[j] = arr[j+1];//第二个元素赋值给第一个元素,由于第一个元素咱们已经存储在中间变量中了,因此咱们不用担忧它的值会被覆盖掉 arr[j+1] = temp;//temp存储了第一个元素的值,把它赋值给第二个元素,就是把第一个元素赋值给第二个元素了,到这一步,两个元素已经交换位置了 }
再介绍一下,冒泡排序的算法过程:
冒泡排序:经过对相邻元素的对比,并交换位置,一步一步的把一个元素给挑选出来。
举个例子,对下面的数组进行排序:
这是一个无序的数组:2,9,4,8,5,1,0,7,3,6
比较规则:大于>
第一轮:
第一次比较:咱们把2和9做比较:2>9吗 ?2和9比较是假,那么咱们无论它,继续向前。
第二次比较:9和4作比较,9>4吗 ? 是真,那么咱们让它们交换值,交换了值,它们的位置不就变了吗,是吧?怎么交换值上面已经讲过,这里再也不重复了。
通过此次交换值,原来的数组已经变成:2,4,9,8,5,1,0,7,3,6
第三次比较:9和8作比较,9>8吗 ? 是真,那么它们两个继续交换值,此时,数组已经变成:2,4,8,9,5,1,0,7,3,6
......................
看到这里9的位置了吗?它是否是一步一步日后移?第一次比较由于9原本就是大的,因此,它不该该和2交换位置,所以,9没有被放到前面去,第二次比较,由于9比4大,因此,根据比较规则,它们应该互换位置,也就是9向后移了一位,第三次比较,依然符合比较规则,因此9和8互换位置了,9又向后移了一步,接下来的比较和上面的比较是同样的过程,你本身比较想象一下吧,这里就再也不重复了。
比较到最后一次:原数组的状况应该是:2,4,8,5,1,0,7,3,6,9
通过第一轮的比较,咱们已经把最大的元素给放到最后面去了,对吧?
接下来,第二轮:
首先说一下,第二轮的时候,原来的数组2,9,4,8,5,1,0,7,3,6,已经变成了2,4,8,5,1,0,7,3,6,9,咱们是在已经冒泡过一次的数组的基础上进行比较的,先确认这一点,要是你还认为是最初的数组,那么,接下来的比较你会被搞糊涂的。呵呵。
此刻的数组:2,4,8,5,1,0,7,3,6,9
根据比较规则:2>4 吗?是假,无论它,继续向前比较。
4>8吗?是假,无论它,继续向前比较。
8>5吗?是真,二者交换值,也就是互换位置,此刻数组:2,4,5,8,1,0,7,3,6,9
继续向前,8>1吗?是真,二者交换位置,此刻数组:2,4,5,1,8,0,7,3,6,9
.......
比较到最后,原数组又发生了改变,已经变成:2,4,5,1,0,7,3,6,8,9
通过两轮的比较,原数组是否已经变得有序一点了?呵呵,没有错,两轮以后,最后面的两位数已是有序的了。
既然两轮以后,最后面的两位已是有序的了,那么,十轮以后呢?你本身想象一下。
十轮以后,这个数组确定已经排序好了。这就是冒泡排序的工做过程,相邻元素比较,每一轮冒泡出一个有序的值。
那么,咱们怎么用代码的方式实现冒泡排序呢?
写到这里,我想你们应该知道怎么作了吧?
咱们用两层嵌套的for循环来实现这个过程,也就是实现冒泡排序:
//外层控制轮数 for(var i=0;i<len;i++){ //内层对数组元素进行冒泡选择 for(var j=0;j<len-1-i;j++){ //交互元素 if(arr[j] > arr[j+1]){ var temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } }
上面那两个嵌套的for循环看到了吗?外层的for循环,咱们就是用来控制比较········轮数········的,
内层的for循环,咱们用来控制···················每一轮的比较次数··················的,同时,在这个for循环里面,咱们还要作什么呢?上面的文字叙述,你看懂了吗?上面的文字叙述中,咱们是否是在···每一次比较···的时候,都要根据比较规则来交换数组元素的位置,是吧?那么,程序的工做过程也是同样的,咱们也要在这里根据比较规则对数组的元素进行交换位置,为的是冒泡出咱们须要的元素。
下面是冒泡排序的完整代码,我对他进行了优化,固然,若是还能够优化,你也能够继续优化的。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-cn"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title>冒泡排序</title> <meta name="keywords" content="关键字列表" /> <meta name="description" content="网页描述" /> <link rel="stylesheet" type="text/css" href="" /> <style type="text/css"></style> <script type="text/javascript"> //参数数字数组 function bubble(arr){ //检查参数 if(toString.call(arr) !== '[object Array]'){ return false; } //获取数组长度 var len = arr.length; if(len <= 1){//小于1不用排序 return arr; } //外层控制轮数 for(var i=0;i<len;i++){ //标记是否有排序的元素 var mark = true; //内层对数组元素进行冒泡选择 for(var j=0;j<len-1-i;j++){ //交互元素 if(arr[j] > arr[j+1]){ mark = false; var temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } if(mark){ //当没有进行冒泡选择时,证实已经排序好了 return arr; } } } //测试 var ar = [9,3,7,4,8,2,5,1,6,0]; alert(bubble(ar)); </script> </head> <body> </body> </html>
这里只是简单的介绍冒泡排序的工做原理,假若有时间,我再详细讲解一下另外三个排序,快速排序、选择排序、插入排序。
其实这三个排序的工做原理都和冒泡排序很类似,网上也有不少文章介绍,你们能够本身研究一下。