整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

javaScript 冒泡排序算法

组的排序方法非常多,其中有封装好的sort()方法,也有js原生语句实现的冒泡排序、快速排序和选择排序等算法。以下介绍冒泡排序的算法。

var arr=[6,5,4,3,2,1];实现从小到大排序

冒泡排序:数组内前后两两比较,如果前者大于后者,则交换两者位置,直到所有的元素都按照从小到大排列,结束排序。

原理:两两比较,始终将较大的数放在后面

代码

var arr=[6,5,4,3,2,1];
   //执行arr.length-1次循环,因为每次循环都会固定一位最大的数放在最后位置,当第五次循环时,结果会将最大的数放在arr[1],排序结束
   for(var i=0;i<arr.length-1;i++){
   //决定每轮元素比较多少次,当每次轮结束时,会将最大的数放在最后,下一轮比较时,最后固定的较大的数可以不再比较,所以j<arr.length-1-i.
     for(var j=0;j<arr.length-1-i;j++){
   //每次比较时,如果前者大于后者,则调换二者位置
       if(arr[j]>arr[j+1]){
         //两个元素互换值,应该定义第三变量,下方赋值原理为:arr[j+1]--->temp;arr[j]--->arr[j+1];temp--->arr[j]
         var temp=arr[j+1];
         arr[j+1]=arr[j];
         arr[j]=temp;
       }
     }
   }

比较过程

第一轮

第1次比较:5 6 4 3 2 1

第2次比较:5 4 6 3 2 1

第3次比较:5 4 3 6 2 1

第4次比较:5 4 3 2 6 1

第5次比较:5 4 3 2 1 6

第二轮 (第一轮结束最后一位最大的数6不再比较)

第1次比较:4 5 3 2 1

第2次比较:4 3 5 2 1

第3次比较:4 3 2 5 1

第3次比较:4 3 2 1 5

第三轮 (第二轮结束最后一位最大的数5不再比较)

第1次比较:3 4 2 1

第2次比较:3 2 4 1

第3次比较:3 2 1 4

第四轮 (第三轮结束最后一位最大的数4不再比较)

第1次比较:2 3 1

第2次比较:2 1 3

第五轮 (第四轮结束最后一位最大的数3不再比较)

第1次比较: 1 2

泡排序是一个很经典的面试题,每次排序都能将最大的数字排到最后,或者将最小的数字排到最前面。现在有一个问题如下:

1、问题

如果要对下面这一组数据从小到大进行排列,你肯定会说,我直接一看就能看出来,一分钟就能排出顺序来。

[75,66,33,34,31,337,65,346]

那是因为这里的数字只有8个,如果有800个呢?

所以我们得靠计算机,得用算法。

为了方便起见,我们就把这8个数字想象成800个,原理是一样的,先看看冒泡排序是怎样的思想吧。

2、冒泡排序思想

  • 基本思想: 冒泡排序,类似于水中冒泡,较大的数沉下去,较小的数慢慢冒起来,假设从小到大,即为较大的数慢慢往后排,较小的数慢慢往前排。
  • 直观表达,每一趟遍历,将一个最大的数移到序列末尾。

结论:每次循环从起始位置 n 与 n+1 进行对比,符合条件就互相调换。

3、基本原理

从后往前(或从前往后)两两比较相邻元素的值,若为逆序,则交换它们,直到序列比较完。称这样过程为一趟冒泡排序,最多只需n-1趟排序。 每一趟排序都可以使一个元素移动到最终位置,已经确定最终位置的元素在之后的处理中无需再对比。 如果某一趟排序过程中未发生“交换”,则算法可提前结束。

4、排序算法

冒泡排序流程图:

4.1、javascript实现代码

<script type="text/javascript">
 function maopao(array){
     var temp;
     for(var i=0;i<array.length;i++){ //比较多少趟,从第一趟开始
        for(var j=0;j<array.length-i-1;j++){ //每一趟比较多少次数
           if(array[j]>arra[j+1]){
              temp=array[j];
              array[j]=array[j+1];
              array[j+1]=temp;
           }
        }
     };
     return array;
 }

 var numbers=[65,4,43,37,31,17,6,46];
 var s=maopao(numbers);
 console.log(s);
</script>

4.2、java实现代码

java冒泡排序跟javascript冒泡排序肯定原理是相同的,不同的就是语言不同,下面就来实现java的冒泡排序。

    public static void main(String[] args) {
         int[] arr = {3,2,3,4,5};
        for (int i = 0; i < arr.length-1; i++) {
            for (int j = 0; j <arr.length-1-i; j++) {
                if (arr[j] > arr[j+1]) {
                    temp(arr, j, j+1);
                }
            }
        }
    }

在面试时能写出以上代码,基本没啥问题了,但是还有种最优的选择就是使用递归方式,把下面方式写出来,面试官会对你刮目相看的。

优化冒泡排序并测试其最好时间复杂度

冒泡排序通过循环将数组中相邻的两个值进行对比、交换已到达排序的目的。那么,对于相同长度的已排序数组和未排序数组来说,它们所消耗的时间是一样的。

5、使用递归优化冒泡排序

冒泡排序方法(下面方法默认使用从小到大有序排列的数组)

  public static void bubbleSort(int[] arr) {
        for (int i = 0; i < arr.length-1; i++) {
            long start = System.currentTimeMillis();
            /*
            通过递归来逐一判断是否有 arr[n] > arr[n+1] 或者 arr[n] > arr[n+1]的情况
                1.当数组为有序时,最快时间复杂度为n
                2,当数组完全无序时,时间复杂度会比普通的冒泡排序高
            */
            boolean flag = recursion(arr,i);
            long end = System.currentTimeMillis();
            System.out.println("递归所用时间:"+(end-start));
             // 如果flag==true,则数组是有序的,直接结束排序方法
            if (flag) break;    
            for (int j = 0; j <arr.length-1-i; j++) {
                if (arr[j] > arr[j+1]) {
                    temp(arr, j, j+1);
                }
            }
        }
    }
    // 打印
    public static void print_b(int[] arr) {
        System.out.print("[");
        for (int i = 0; i < arr.length; i++) {
            if( i == arr.length-1 ) System.out.print(arr[i]);
            else System.out.print(arr[i] + ",");
        }        
        System.out.println("]");
    }
    // 交换
    public static void temp(int[] arr , int num1,int num2) {
        int temp  = arr[num1];
        arr[num1] = arr[num2];
        arr[num2] = temp;
    }

递归方法

  1. 调用方法传递数组arr和当前数组下标n;
  2. 通过递归对下标为n的值和下标为n+1 的值对比。
  • 当 n == arr.length-1,即n已经到达数组最后一个值的下标时,返回true;
  • 当存在 arr[n] > arr[n+1] 时返回 false 并结束方法。


 // 递归
    public static boolean recursion(int[] arr,int n ) {
        if (n == arr.length-1) {
            return true;
        }else if (arr[n] > arr[n+1] ) {
            return false;
        }
        return recursion(arr, n+1);
    }

小结

1.冒泡排序一般是通过两层循环进行处理,第一层循环主要为了让冒泡排序成功,数组需要进行多少次大循环,这里我们确定了在一个大于等于两个数字的数组时(因为只存在一个数字的数组不需要排序),确定一个数字的排序就需要一个大循环,即n个数字有n-1次大循环;第二层循环主要是将数组的第一个数字与其后面的数字进行比较,然后确定排序。

2.综上所述,在第二层循环完成的时候,第一层大循环也完成了一次,因此该数组就已经确定好了一个数字的排序在所有循环完成后,冒泡排序(数字从小到大)就完成了。

3.说白了就是1和2比,把大的放后面,2和3比,一样,大的放后面,3和4比,直到比完一圈,这样的话,最大的永远被放后面,于是就排了最后一个了,把前面的n-1个再来一遍,于是又有一个最大值,再来,最后排完了。

4.冒泡排序由于比较简单和容易理解,往往会成为面试时首先想到的排序算法问题。小伙伴如果能手写出来,完全不怕面试啦。

件传递有两种方式,冒泡和捕获。事件传递定义了元素事件触发的顺序,在冒泡中,内部元素的事件会先被触发,然后在触发外部元素,如先触发p元素然后触发div元素。在捕获事件中,外部元素先被触发,然后内部事件触发。addEventListener() 方法可以指定 "useCapture" 参数来设置传递类型:addEventListener(event, function, useCapture);

创建新的HTML元素(节点)appendChild()

HTML Collection与NodeList的区别:NodeList 与 HTMLCollection 有很多类似的地方。NodeList 与 HTMLCollection 都与数组对象有点类似,可以使用索引 (0, 1, 2, 3, 4, ...) 来获取元素。NodeList 与 HTMLCollection 都有 length 属性。节点列表不是一个数组!节点列表无法使用数组的方法: valueOf(), pop(), push(), 或 join() 。