美文网首页
排序算法总结及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

相关文章

  • 一文搞定十大经典排序算法(Java实现)

    本文总结十大经典排序算法及变形,并提供Java实现。参考文章:十大经典排序算法总结(Java语言实现)快速排序算法...

  • 排序算法总结及JS实现

    目录:1.冒泡排序2.选择排序3.插入排序4.归并排序5.快速排序6.堆排序 冒泡排序 冒泡排序比较任何两个相邻的...

  • 算法-排序算法总结

    排序类型总结 1 排序算法基础实现 2 排序算法应用 2.1 基础排序 2.2 计数排序应用 2.3 快排应用 2...

  • 数据结构与算法第七讲 - 排序(上)

    对于排序算法,主要掌握内容如下: 排序算法的实现原理 手写出实现代码 评价及分析算法 本讲内容 如何分析一个排序算...

  • 排序算法最强总结及其代码实现(Python/Java)

    前言 本文总结了常用的全部排序算法,内容包括: 排序算法的定义和思路 排序算法的代码实现:Python和Java,...

  • 排序

    八大排序算法 一、归并排序 递归及非递归的JAVA实现 二、快速排序 快排算法JAVA实现 三、堆排序 堆排序堆排...

  • python实现计数排序(CountSort)

    python实现【计数排序】(CountSort) 算法原理及介绍 计数排序不是基于比较的排序算法,其核心在于将输...

  • 7大经典的排序算法总结实现

    作者 : 专注J2EE来源 : 博客园 常见排序算法总结与实现 本文使用Java实现这几种排序。以下是对排序算法总...

  • python实现选择排序(SelectionSort)

    python实现【选择排序】 算法原理及介绍 选择排序(Selection-sort)是一种简单直观的排序算法。它...

  • 常用排序算法

    常用的排序算法 在此总结一下常用排序算法的代码实现 #include using namespace std;t...

网友评论

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

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