冒泡排序、插值法排序、二分法排序和快速排序的个人理解
排序的各种算法,没有任何计算机语言基础的我,是在刚开始接触javascript就有了解过的。当时听得我糊里糊涂,心里千万个草泥马在奔腾,怎么javascript这么难,算法又是什么鬼东西呀。后来慢慢接触javascript后又看了两三次有关排序算法的视频,看懂之后我的感慨就是:原来计算机是这么笨的,所有数值都要一个个来比较才知道它的大小。
我也由于各种懒癌,各种综合症博客一直都没有写。这个排序的算法让我觉得挺有意思的,也花了不少的时间在上面,所以就记录一下吧。
首先是冒泡排序:
我就只写javascript的部分了,其余的请自动在编译器或者脑子里添加。
1 <script type="text/javascript"> 2 /*个人理解:冒泡算法的思路就是, 3 *在原数组上,从arr[0]开始, 4 *拿arr[0]与arr[1]、arr[2]...arr[arr.length-1]进行比较; 5 *如果arr[0]>arr[n],则两者交换位置(这里是升序排序,降序则将大于号改为小于号),此时,arr[0]的值已经更改了 6 *当arr[0]与arr中的所有数比较完成后,即求出了数组中最小的值,并且将其排在了第一位。 7 *接着到arr[1]与arr[2]...arr[arr.length-1]的数进行比较,完成后arr[1]就是余下的数中最小的数(除了arr[0]) 8 *依次到arr[2]...arr[arr.length-2]分别与后面的数进行比较。完成后就得到了一个升序的数组了。 9 *冒泡的意思就是,先求出最小的把它放在第一位,然后是倒数第二小的把它放在第二位,依次排序,就像泡泡一个个往上 冒起一样。*/ 10 var Arr = [12,5,37,42,64,41,2,14,6,22]; 11 function babblingSort(arr){//封装一个函数,传入arr 12 var len = arr.length; 13 for(var i=0;i<len;i++){ 14 for(var j=i+1;j<len;j++){//想想这里为什么是j=i+1??? 15 if(arr[i]>arr[j]){ 16 var temp = arr[i];//另外建一个变量用来存储arr[i]以便进行数值交换 17 arr[i] = arr[j]; 18 arr[j] = temp; 19 } 20 } 21 } 22 for(var i=0;i<len;i++){ 23 document.write(arr[i]+",");//也可以直接打印arr. 24 } 25 }; 26 babblingSort(Arr);//调用函数 27 </script>
插值法排序:
1 <script type="text/javascript"> 2 //插值法排序 3 /*个人理解: 4 *另外建一个新数组 5 *令新数组的第一个值等于原数组的第一个值 6 *然后原数组从第二个值开始(第一个已经放进了新数组),将其余新数组的每一项进行比较, 7 *将小于放前面,大的放后面(看例子可了解具体执行过程)*/ 8 9 var Arr = [12,5,37,42,64,41,2,14,6,22]; 10 function insetSort(arr){ 11 var arrSort = []; //新建一个空数组 12 arrSort[0] = arr[0]; //令新数组首项等于原数组首项 13 var len = arr.length; 14 var flag; 15 for(var i=1;i<len;i++){ 16 flag = 0; 17 var sortLen = arrSort.length; 18 for(var j=0;j<sortLen;j++){ 19 //从左到右遍历新数组中的数,如果出现大于arr[i]的值,则把arr[i]存放于该数值的位置,并跳出循环。 20 if(arr[i]<arrSort[j]){ 21 arrSort.splice(j,0,arr[i]); 22 flag = 1; 23 break; 24 } 25 } 26 if(flag==0){//如果该数值大于arrSort中的任意数值,则会存放到最后。 27 arrSort.push(arr[i]); 28 } 29 30 } 31 len = arrSort.length; 32 for(var i=0;i<len;i++){ 33 document.write(arrSort[i]+","); 34 } 35 } 36 insetSort(Arr); 37 </script>
二分法排序:
1 <script type="text/javascript"> 2 3 // 类似于插值法排序,只是将比较的方式改变了,如果理解了前两种排序方法二分法排序也很容易理解的,这里不做详解了 4 var Arr = [12,5,37,42,64,41,2,14,6,22]; 5 function halfSort(arr){ 6 var nArr =[]; 7 nArr[0] = arr[0]; 8 var len = arr.length; 9 var left = 0; 10 var right = 0; 11 var point = 0; 12 13 for(var i=1;i<len;i++){ 14 left = 0; 15 var nlen = nArr.length; 16 right = nlen; 17 for(var j=0;j<nlen;j++){ //这里的j仅代表循环的次数 18 point = Math.floor((left+right)/2); //Math.ceil(),Math.floor的区分 19 if(nArr[point]<arr[i]){ //若该值为true,则arr[i]应排在新数组中间右边的位置 20 left = point+1; //再依次加一,即向右逐个比较数组的每个数。这里貌似可以改良。我水平有限不懂 21 }else{ 22 right = point;//arr[i]与nArr[point]已经作过比较,所以arr[i]只需与nArr[point]前面的point个数比 23 } 24 if (left==right) { 25 nArr.splice(left,0,arr[i]); 26 break; 27 } 28 } 29 30 } 31 var nlen = nArr.length; 32 console.log(nArr[7]); 33 for(var i=0;i<nlen;i++){ 34 document.write(nArr[i]+","); 35 } 36 } 37 halfSort(Arr); 38 </script>
快速排序:
1 /* 2 *首先要了解concat()函数和函数的递归操作 3 *1.找一个基准点 4 *2.建立两个数组,分别存储左边和右边的数组 5 *3.利用递归,进行拆分,用concat()函数将其拼接起来 6 */ 7 function quickSort(arr){ 8 9 if(arr.length<=1){ 10 return arr;//想想这里为什么要返回arr呢? 11 } 12 13 var num = Math.floor(arr.length/2); 14 15 var numValue = arr.splice(num,1); //求出数组索引值的中间值,这个例子中的第一个numValue是:41 16 var left = []; 17 var right = []; 18 19 for(var i=0;i<arr.length;i++){ 20 var j = i; 21 if(arr[i]<numValue){ //把小于numValue的数存到左边 22 left.push(arr[i]); 23 } 24 else{ //把大于numValue的数存到右边 25 right.push(arr[i]); 26 } 27 } 28 29 /*document.write('L:'+left+"<br>"); //可以试着打印left值和right值,查看数组的具体拆分, 30 *document.write('R:'+right+"<br><br>"); 31 *下面数字表示执行的顺序 32 * ① L:12,5,37,2,14,6,22,40 R:42,64 33 * 34 * ② L:12,5,2,6 R:37,22,40 ⑧ L:42 R:空 35 * 36 * ③ L:空 R:12,5,6 ⑥ L:空 R37,40 37 * 38 * ④ L:空 R:12,6 ⑦ L:37 R:空 39 * 40 * ⑤ L:空 R12 41 * 以上的每个被拆分的数组都会传入quickSort() 函数,当值为空或者只有一个数的时候 42 * 就返回了空值或那个数值,结束了当前分支的循环(循环使用quickSort()函数)。 43 * 44 */ 45 46 return quickSort(left).concat([numValue],quickSort(right));//这是总的返回值 47 }
var Arr = [12,5,37,42,64,41,2,14,6,22];
48 var result = quickSort(Arr);
49 document.write(result);
以上是个人对四种排序方法的理解。在学习的过程中,算法总让我感到困难而又感觉挺有意思的,特别是用枚举法解决数学问题的时候,让我有点惊喜的感觉(我只是个小菜鸟,大家有啥看法可以随便说)。没有计算机语言基础的我,在之前犹豫了一段时间后还是选择了码农这条路。到现在也差不多自学了3、4个月了,期间还算努力,HTML 、CSS、javascript、jQuery基本都算入门了。现在就快得开始找工作了,心里各种担忧,各种“万一”、“怎么办”。早晚还是得面对的。