zoukankan      html  css  js  c++  java
  • JS的排序算法

    排序是最基本的算法(本文排序为升序Ascending),常见的有以下几种:

    1、冒泡排序 Bubble Sort

    2、选择排序 Selection Sort

    3、插入排序 Insertion Sort

    4、快速排序 Quick Sort

    5、归并排序 Merge Sort

    冒泡排序 Bubble Sort

    冒泡排序是最慢的排序算法,同时也是最直观、最容易想到的排序方法。

    步骤

    1、比较第一个和第二个元素,若第一个元素大于第二个元素,则交换位置。

    2、若第一个小于第二个元素,则继续比较第二个和第三个元素,重复步骤1。

    3、经过第一轮比较,则至少最大的元素已经被移动到数组最后一个位置,就像“气泡冒出了水面”一样。

    4、继续重复步骤1和步骤2

    5、排序成功。

    代码

    function bubbleSort(arr){
        var temp, swapped;
        do {
            // 若本轮循环中,已经没有任何元素交换位置,则说明排序已经完成,退出循环
            swapped = false;
            for(var i =0;i<arr.length;i++){
                if(arr[i] > arr[i+1]) {
                    // 若arr[i] > arr[i+1],则交换arr[i]和arr[i+1]
                    temp = arr[i+1];
                    arr[i+1] = arr[i];
                    arr[i] = temp;
                    swapped = true;
                }
            }
        } while (swapped)
        return arr;
    }

    时间复杂度

    O(n2)

    选择排序 Selection Sort

    在未排序中选择最小的,放在数组第一个位置。然后从剩余未排序数组中,选择最小的,放在第二个位置。遍历重复,最终完成排序。

    和冒泡排序一样,时间复杂度太大,实际中不会用到。

    步骤

    1. 假设第一个元素是最小的,最小的位置记为minIndex=0。依次和后面的元素比较,若第i个元素更小,则更新minIndex=i,一直到数组最后一个元素。

    2. 第一遍遍历之后,若minIndex与开始假设最小的位置不同,则交换元素。

    3. 重复步骤1和步骤2,直到排序完成。

    代码

    function selectSort(arr) {
        var length = arr.length,
            swap,
            min;
        for (var i = 0; i < length; i++) {
            // 假设第i个是最小的,min=i
            min = i;
            for (var j = i + 1; j < length; j++) {
                // 如果第j个更小,则min=j
                if (arr[min] > arr[j]) {
                    min = j;
                }
            }
            // 如果假设的最小的和实际中最小的,不是同一个位置的,则交换位置
            if (min != i) {
                swap = arr[min];
                arr[min] = arr[i];
                arr[i] = swap;
            }
        }
        return arr;
    }

    时间复杂度

     O(n2)

    插入排序 Insertion Sort

    假设数组分为左右两个部分:左侧是已排序(Sorted)的,右侧是未排序(Unsorted)的。从右侧未排序中,依次取出一个元素,倒序和排序好的元素对比,放在不大于已排序的位置。

    步骤

    1. 取出第一个元素,可以认为是已排序的。

    2. 取出下一个元素,在已排序中从后向前扫描。

    3. 若该元素(已排序)大于新元素,则该元素向后移一位。

    4. 重复步骤3,直到直到找到已排序的元素小于或者等于新元素的位置

    5. 将新元素插入到该位置后

    6. 重复步骤1到步骤5.

    代码

    function insertionSort(arr) {
        var length = arr.length,
            temp, j;
        for (var i = 0; i < length; i++) {
            // 取得第i个元素,标记为temp
            temp = arr[i];
            j = i - 1;
            // 依次和前面的元素比较,若前面的元素大于temp,则元素向后移动一位,直到不满足条件
            while (j >= 0 && arr[j] > temp) {
                arr[j + 1] = arr[j];
                j--;
            }
            arr[j + 1] = temp;
        }
        return arr;
    }

    快速排序 Quick Sort

    快速排序是一种有效率的排序方式。

    步骤

    1. 选择一个基准元素,通常选择中间的元素。

    2. 遍历数组,将比基准元素小的元素放到左边,比基准元素大的元素放到右边。

    3. 重复步骤1和步骤2。

    代码

    function quickSort(arr) {
        // 空数组或是一个元素的数组,直接返回数组
        if (arr.length <= 1) return arr;
        // 取出基准元素
        var pivot = arr.splice(Math.floor(arr.length / 2), 1)[0],
            left = [],
            right = [];
        for (var i = 0, length = arr.length; i < length; i++) {
            // 和基准元素比较大小,分别放在left和right数组中
            if (arr[i] <= pivot) {
                left.push(arr[i])
            } else {
                right.push(arr[i])
            }
        }
        // 递归操作
        return quickSort(left).concat(pivot, quickSort(right))
    }

    时间复杂度

    平均时间复杂度:O(NlogN)

    归并排序 Merge Sort

    是一种分治(divide and conquer )的算法。

    将数组拆分(divide)为小的数组,对小的数组继续拆分,重复操作直至每个数组的元素只有一个。然后比较大小,进行合并。

    步骤

    1、递归分割数组,直至最小的数组只有一个元素。

    2、两个相邻的最小数组单元比较大小,完成排序。

    3、两个次一级的最小数组单元比较大小,完成排序。

    4、重复操作,完成排序。

    代码

    // eg:   mergeSort([1,  3, 8, 3, 5, 3, 5, 22])
    // divide function:递归将函数切分为只有一个元素的数组
    function mergeSort(arr) {
        if (arr.length < 2) return arr;
        var mid = Math.floor(arr.length / 2),
            left = arr.slice(0, mid),
            right = arr.slice(mid);
        return merge(mergeSort(left), mergeSort(right));
    }
    // conquer function  合并,将分割开的数组合并起来
    function merge(left, right) {
        var lLength = left.length,
            rLength = right.length,
            lIndex = 0,
            rIndex = 0,
            result = [];
        // left和right都是已经排序好的
        // 依次比较每个元素大小,将小的元素push进result,直至left或是right中的任意一个元素都已经被push进result
        while (lIndex < lLength && rIndex < rLength) {
            if (left[lIndex] <= right[rIndex]) {
                result.push(left[lIndex++])
            } else {
                result.push(right[rIndex++])
            }
        }
        // 这两种是一样的,因为此时left.slice(lIndex)和right.slice(rIndex)必定有一个是空元素
        // return result.concat(left.slice(lIndex)).concat(right.slice(rIndex))
        return result.concat(left.slice(lIndex)).concat(right.slice(rIndex))
    }

    时间复杂度

    [参考资料]

    JS用到的排序:http://khan4019.github.io/front-end-Interview-Questions/sort.html

    JS用到的排序:https://juejin.im/post/57dcd394a22b9d00610c5ec8 

    可视化的JS排序网站:http://jsdo.it/norahiko/oxIy/fullscreen

    冒泡排序:http://www.stoimen.com/blog/2010/07/09/friday-algorithms-javascript-bubble-sort/

    选择排序:https://www.nczonline.net/blog/2009/09/08/computer-science-in-javascript-selection-sort/

    插入排序:http://codingmiles.com/sorting-algorithms-insertion-sort-using-javascript/

    快速排序:http://www.ruanyifeng.com/blog/2011/04/quicksort_in_javascript.html

  • 相关阅读:
    本学期的学习计划
    snmp 学习记录
    解锁树莓派root账号
    树莓派通过阿里云内网穿透,搭建下载机
    golang Ordered Map
    go 切片slice奇怪的地方
    学习scons总结
    go语言学习小结
    学习git版本管理工具
    轻松记账工程冲刺第二阶段10
  • 原文地址:https://www.cnblogs.com/oneplace/p/8324406.html
Copyright © 2011-2022 走看看