美文网首页
排序算法总结及JS实现

排序算法总结及JS实现

作者: 壹豪 | 来源:发表于2019-08-23 10:04 被阅读0次

    目录:
    1.冒泡排序
    2.选择排序
    3.插入排序
    4.归并排序
    5.快速排序
    6.堆排序

    冒泡排序

    冒泡排序比较任何两个相邻的项,如果第一个比第二个大,则交换它们。元素项向上移动至正确的顺序。

    function bubbleSort(arr){
        var len = arr.length;
        for(var i=0;i<len;i++){
            for(var j=0;j<len-1-i;j++){      //内循环减去外循环中已跑过的次数,可以避免内循环中所有不必要的比较
                if(arr[j]>arr[j+1]){
                    [arr[j], arr[j+1]] = [arr[j+1], arr[j]];
                }
            }
        }
        console.log(arr);
    }
    

    测试:

    bubbleSort([9,8,7,6,5,4,3,2,1]);      //[1,2,3,4,5,6,7,8,9]
    

    时间复杂度:O(n²)

    选择排序

    选择排序算法是一种原址比较算法。选择排序的思路是:找到数据结构中最小值并将其放置在第一位,接着找到第二小的值将其放在第二位,依此类推。

    function selectionSort(arr){
        var len = arr.length;
        var index = null;
        for(var i = 0; i< len - 1;i++){
            index = i;
            for(var j = i;j<len;j++){
                if(arr[index] > arr[j]){
                    index = j;
                }
            }
            if(i != index){
                [arr[i], arr[index]] = [arr[index], arr[i]];
            }
        }
        console.log(arr);
    }
    

    测试:

    selectionSort([2,1,3,5,8,6,7,3]);       //[ 1, 2, 3, 3, 5, 6, 7, 8 ]
    

    时间复杂度:O(n²)

    插入排序

    插入排序每次排一个数组项,以此方式构建最后的排序数组。假如第一项已经排序好了,接着,它和第二项进行比较,第二项是应该呆在原位置,还是插入到第一项之前呢?这样前两项就已正确排序,接着和第三项比较,依此类推。

    function insertSort(arr){
        var len = arr.length,
        j,
        temp;
        for(var i = 1; i<len;i++){
            j = i;
            temp = arr[i];
            while(j>0&&arr[j-1] > temp){
                arr[j] = arr[j-1];
                j--;
            }
            arr[j] = temp;
        }
        console.log(arr);
    }
    

    测试:

    insertSort([1,3,2,7,5,9,2]);      //[ 1, 2, 2, 3, 5, 7, 9 ]
    

    时间复杂度:O(n²)
    插入排序在排序小型数组时,比选择排序和冒泡排序的性能要好

    归并排序

    归并排序是一种分治算法。其思想是将原始数组切分成较小的数组,直到每个小数组只有一个位置,接着将小数组归并成较大的数组,直到最后只有一个排序完成的大数组。

    function mergeSort(arr){
        mergeSortRec(arr)
    }
    function mergeSortRec(arr){
        var len = arr.length;
        if(len === 1){           //递归终止条件
            return arr;
        }
        var mid = Math.floor(len / 2);
        var left = arr.slice(0, mid);
        var right = arr.slice(mid, len);
        return merge(mergeSortRec(left), mergeSortRec(right));
    }
    function merge(left, right){
        var res = [];
        var le = 0;
        var re = 0;
        while(le<left.length && re<right.length){
            if(left[le] < right[re]){
                res.push(left[le++]);
            }
            else{
                res.push(right[re++]);
            }
        }
        while(le < left.length){
            res.push(left[le++]);
        }
        while(re < right.length){
            res.push(right[re++]);
        }
        console.log(res);
        return res;
    }
    

    测试:

    var array = [1,3,2,6,4,8,5];
    mergeSort(array);
    

    输出:

    [2,3]
    [1,2,3]
    [4,6]
    [5,8]
    [4,5,6,8]
    [1,2,3,4,5,6,8]
    

    时间复杂度:O(nlogn)

    快速排序

    和归并排序一样,快速排序也使用分治的方法,将原始数组分为较小的数组。
    (1)首先,从数组中选择中间一项作为主元;
    (2)创建两个指针,左边一个指向数组的第一项,右边一个指向数组的最后一项。移动左指针直到我们找到一个比主元大的元素,接着,移动右指针直到找到一个比主元小的元素。然后交换它们,重复这个过程,直到左指针超过了右指针。这个过程将使得比主元小的值都排在主元之前,比主元大的值都排在主元之后。这一步叫做划分操作。
    (3)接着,算法对划分后的小数组重复之前的两个步骤,直至数组已完全排序。

    function quickSort(arr){
        quick(arr, 0, arr.length-1);
        console.log(arr);
    }
    function quick(arr, left, right){
        var index;
        if(arr.length > 1){
            index = partition(arr, left, right);
            if(left < index-1){
                quick(arr, left, index-1);
            }
            if(index < right){
                quick(arr, index, right);
            }
        }
    }
    function partition(arr, left, right){
        var p = arr[Math.floor((left+right) / 2)],
        i = left,
        j = right;
        while(i <= j){
            while(arr[i] < p){
                i++;
            }
            while(arr[j] > p){
                j--;
            }
            if(i <= j){
                [arr[i], arr[j]] = [arr[j], arr[i]];
                i++;
                j--;
            }
        }
        return i;
    }
    

    时间复杂度:O(nlogn)

    理解了上面的代码,就可以看下面的简洁版了

    function quickSort(arr,l,r){
      if(l < r){
        var i = l, j = r, x = arr[i];
        while(i<j){
          while(i<j && arr[j]>x)
            j--;
          
          if(i<j)
            //这里用i++,被换过来的必然比x小,赋值后直接让i自加,不用再比较,可以提高效率
            arr[i++] = arr[j];
          
          while(i<j && arr[i]<x)
            i++;
          
          if(i<j)
            //这里用j--,被换过来的必然比x大,赋值后直接让j自减,不用再比较,可以提高效率
            arr[j--] = arr[i];
        }
        arr[i] = x;
        
        quickSort(arr, l, i-1);
        quickSort(arr, i+1, r);
      }
    }
    

    堆排序

    堆排序也是一种很高效的算法,它把数组当作二叉树来排序。它将数组当作二叉树来管理:
    (1)索引0是树的根节点
    (2)除根节点外,任意节点N的父节点是N/2
    (3)节点L的左子节点是2L
    (4)节点R的右子节点是2R+1

    function heapSort(arr){
        var heapSize = arr.length;
        buildHeap(arr);
        while(heapSize > 1){
            heapSize--;
            [arr[0], arr[heapSize]] = [arr[heapSize], arr[0]];
            heapify(arr, heapSize, 0);
        }
        console.log(arr);
    }
    function buildHeap(arr){
        var heapSize = arr.length;
        for(var i = Math.floor(arr.length / 2); i >= 0; i--){
            heapify(arr, heapSize, i);
        }
    }
    function heapify(arr, heapSize, i){
        var left = i*2 + 1,
        right = i*2 + 2,
        largest = i;
        if(left < heapSize && arr[left] > arr[largest]){
            largest = left;
        }
        if(right < heapSize && arr[right] > arr[largest]){
            largest = right;
        }
        if(largest !== i){
            [arr[i], arr[largest]] = [arr[largest], arr[i]];
            heapify(arr, heapSize, largest);
        }
    };
    

    测试:

    heapSort([2,4,1,3]);    //[ 1, 2, 3, 4 ]
    

    时间复杂度:O(nlogn)

    转载自https://blog.csdn.net/q1312882392/article/details/99051748

    相关文章

      网友评论

          本文标题:排序算法总结及JS实现

          本文链接:https://www.haomeiwen.com/subject/phhzsctx.html