冒泡排序进阶优化

冒泡排序的思想:我们以升序排列为例,所谓冒泡排序就是在无序数组中每执行一趟选出这一趟中最大的数放在最后面,第二趟选出次大的数放在倒数第二位上,直到完成排序。以此类推降序就是将小的数放在后面排序。代码如下: 

方法(一)

 1   var arr = [6, 5, 3, 4, 1, 2];
 2     function sort(arr) {
 3         var maxNum= arr.length - 1;
 4         // 遍历数组,次数就是arr.length - 1
 5         for (var i = 0; i < maxNum- 1; i++) {
 6             // 这里根据外层for循环的i,逐渐减少内层 for循环j的次数所以要减i。
 7             for (var j = 0; j < maxNum-i; j++) {
 8                 if (arr[j] > arr[j + 1]) {
 9                     //设置第三方变量(x)来用于数据交换,且这个变量放在循环的外面性能要好,两两对比,把大的数放在后面。
10                     var x = arr[j + 1];
11                     arr[j + 1] = arr[j];
12                     arr[j] = x;
13                     // 利用加法来实现两个数据的交换
14                     // arr[j] = arr[j] + arr[j+1];
15                     // arr[j+1] = arr[j] - arr[j+1];
16                     // arr[j] = arr[j] - arr[j+1];
17                     // 利用位运算实现两个数据的交换
18                     //arr[j] = arr[j]^arr[j+1];
19                     //arr[j+1] = arr[j]^arr[j+1];
20                     //arr[j] = arr[j]^arr[j+1];
21                 }
22             }
23             console.log("第" + (i + 1) + "次排序后的数组是" + arr);
24         }
25     }
26     sort(arr);
27     console.log(arr);

运行图:

方法(二)

主要还是对方法一的优化,设置一个标志,如果这一趟下来发生了交换,则为true,否则为false。如果有一趟下来没有发生交换,则说明排序已经完成。代码如下:

 1  var arr = [3, 2, 1, 4,5,6];
 2     function sort(arr) {
 3         var maxNum= arr.length - 1;
 4         // 遍历数组,次数就是arr.length - 1
 5         for (var i = 0; i < maxNum- 1; i++) {
 6             // 声明一个变量,作为标志位
 7             var done = true;
 8             // 这里根据外层for循环的i,逐渐减少内层 for循环j的次数所以要减i。
 9             for (var j = 0; j < maxNum-i; j++) {
10                 if (arr[j] > arr[j + 1]) {
11                     //设置第三方变量(x)来用于数据交换,且这个变量放在循环的外面性能要好,两两对比,把大的数放在后面。
12                     var x = arr[j + 1];
13                     arr[j + 1] = arr[j];
14                     arr[j] = x;
15                     // 利用加法来实现两个数据的交换
16                     // arr[j] = arr[j] + arr[j+1];
17                     // arr[j+1] = arr[j] - arr[j+1];
18                     // arr[j] = arr[j] - arr[j+1];
19                     // 利用位运算实现两个数据的交换
20                     //arr[j] = arr[j]^arr[j+1];
21                     //arr[j+1] = arr[j]^arr[j+1];
22                     //arr[j] = arr[j]^arr[j+1];
23                     done = false;
24                 }
25             }
26             if (done) {
27                 break;
28             }
29             console.log("第" + (i + 1) + "次排序后的数组是" + arr);
30         }
31     }
32     sort(arr);
33     console.log(arr);

运行图:

 

  方法(三)

      是对前两种方式的进一步优化,假如数组长度是30,如果只有前15位是无序排列的,后十五位是有序且都大于前15位,所以第一趟遍历排序的时候发生交换的位置必定小于15,且该位置之后的必定有序,我们只需要排序好该位置之前的就可以,因此我们要来标记这个位置就可以了,代码如下:

 1  var arr = [3, 2, 1, 4, 5, 6];
 2 
 3     function sort(arr) {
 4         var n = arr.length;
 5         var j, k;
 6         var flag = n;
 7         while (flag > 0) {
 8             k = flag;
 9             flag = 0;
10             for (j = 1; j < k; j++) {
11                 if (arr[j - 1] > arr[j]) {
12                     x = arr[j - 1];
13                     arr[j - 1] = arr[j];
14                     arr[j] = x;
15                     flag = j;
16                 }
17             }
18         }
19     }
20     sort(arr);
21     console.log(arr);

 

 总结分析:

         1.比较相邻的两个元素,如果前一个比后一个大(小),则交换位置。

   2.第一轮的时候最后一个元素应该是最大(最小)的一个。

   3.按照步骤一的方法进行相邻两个元素的比较,这个时候由于最后一个元素已经是最大(最小)的了,所以最后一个元素不用比较。

 

 



 


posted on 2019-02-24 19:09  F-dragon  阅读(682)  评论(0编辑  收藏  举报

导航