十大经典排序算法的JS版

排序对比:

排序对比.jpg

排序分类:

排序分类.jpg

  • 冒泡排序(Bubble Sort)
    冒泡排序是一种简单的排序算法,它重复的走访要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来,走访数列的工作是重复的进行直到没有再需要交换,也就是说数列已经排序完成,这个算法的名字的由来是因为越小的元素会精油交换慢慢浮到数列的顶端。
    1.初级版
function bubbleSort(array) {
    const length = array.length;
    for (let i = 0; i < length; i++) {
        for (let j = 0; j < length - 1 - i; j++) {
            if (array[j] > array[j + 1]) {
           let temp = array[j + 1];
                array[j + 1] = array[j];
                array[j] = temp;
            }
        }
    }
    return array;
}

2.改进版
设置一个标志性变量pos,用于记录每趟排序中最后一次进行交换的位置,由于pos位置之后的记录均已交换到位,故在进行下一趟排序是只要扫描到pos位置即可

function bubbleSort(array) {
    let i = array.length - 1;
    while (i > 0) {
        let pos = 0;
        for (let j = 0; j < i; j++) {
            if (array[j] > array[j + 1]) {
                pos = j;
                let temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
            }
        }
        i = pos;
    }
    return array;
}

3.加强版
传统冒泡排序中的每一趟排序操作只能找到一个最大值或者最小值,我们考虑利用在每趟排序中进行正向和反向两遍冒泡的方法一可以得到里那个个最终值(最大及最小),从而使排序趟数至少减少一半

function bubbleSort(array) {
    let low = 0;
    let high = array.length - 1;
    while (low < high) {
        for (let j = low; j < high; j++) {
            if (array[j] > array[j + 1]) {
                const temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
            }
        }
        --high;
    }
    return array;
}
  • 选择排序(Selection Sort)
    表现最稳定的排序算法之一,因为无论什么数据进去都是O(n2)的时间复杂度......所以用它的时候数据规模越小越好,唯一的好处就是不占用额外的内存空间,理论上将,选择排序可能也是平时排序一般人想到的最多的排序方法之一
function selectionSort(array) {
    let length = array.length;
    for (let i = 0; i < length - 1; i++) {
        let minIndex = i;
        for (let j = i + 1; j < length; j++) {
            if (array[j] < array[minIndex]) {
                minIndex = j;
            }
        }
        let temp = array[i];
        array[i] = array[minIndex];
        array[minIndex] = temp;
    }
    return array;
}
  • 插入排序(Insertion Sort)
    插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但是它的原理却是最好理解的,它的工作原理是通过构建有序序列,对未排序的数据,在已排序的序列中从后向前扫描,找到相应的位置并插入
    1.初级版—从后往前插
function insertionSort(array) {
    for (let i = 1; i < array.length; i++) {
        let key = array[i];
        let j = i - 1;
        while (j >= 0 && array[j] > key) {
            array[j + 1] = array[j];
            j--;
        }
        array[j + 1] = key;
    }
    return array;
}

2.升级版—基于二分法

function insertionSort(array) {
    for (let i = 1; i < array.length; i++) {
        let key = array[i], left = 0, right = i - 1;
        while (left <= right) {
            let middle = parseInt((left + right) / 2);
            if (key < array[middle]) {
                right = middle - 1;
            } else {
                left = middle + 1;
            }
        }
        for (let j = i - 1; j >= left; j--) {
            array[j + 1] = array[j];
        }
        array[left] = key;
    }
    return array;
}
  • 希尔排序(Shell Sort)
    希尔排序的核心在于间隔序列的设定。既可以提前设定好间隔序列,也可以动态定义间隔序列。
function shellSort(array) {
    let gap = 1;
    while (gap < array.length / 5) {
        gap = gap * 5 + 1;
    }
    for (gap; gap > 0; parseInt(gap / 5)) {
        for (let i = gap; i < array.length; i++) {
            const temp = array[i];
            for (let j = i - gap; j >= 0 && array[j] > temp; j -= gap) {
                array[j + gap] = array[j];
            }
            array[j + gap] = temp;
        }
    }
    return array;
}
  • 归并排序(Merge Sort)
    归并排序是建立在归并操作的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。归并排序是一种稳定的排序算法,将已有序的子序列合并,等到一个完全有序的序列,即先使每个子序列有序,再使子序列段有序,若将两个有序表合并成一个有序表,称作2路合并
function mergeSort(array) {
    if (array.length < 2) {
        return array;
    }
    const middle = parseInt(array.length / 2);
    const left = array.slice(0, middle);
    const right = array.slice(middle);
    return merge(test_run(left), test_run(right));
}
function merge(left, right) {
    const newArray = [];
    while (left.length && right.length) {
        if (left[0] <= right[0]) {
            newArray.push(left.shift());
        } else {
            newArray.push(right.shift());
        }
    }
    while (left.length) {
        newArray.push(left.shift());
    }
    while (right.length) {
        newArray.push(right.shift());
    }
    return newArray;
}
  • 快速排序(Quick Sort)
    快速排序的基本思想是:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序
    方法一
const quickSort = function (array) {
    if (array.length <= 1) {
        return array;
    }
    const pivotIndex = parseInt(array.length / 2);
    const pivot = Number(array.splice(pivotIndex, 1));
    const left = [];    const right = [];
    for (let i = 0; i < array.length; i++) {
        if (array[i] < pivot) {
            left.push(array[i]);
        } else {
            right.push(array[i]);
        }
    }
    return quickSort(left).concat([pivot], quickSort(right));
};

方法二
其中 left = 0; right = array.length-1

function quickSort(array, left, right) {
    if (left < right) {
        let x = array[right], i = left - 1;
        for (let j = left; j <= right; j++) {
            if (array[j] <= x) {
                i++;
                const temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
        quickSort(array, left, i - 1);
        quickSort(array, i + 1, right);
    }
    return array;
}
  • 堆排序(Heap Sort)
    是指利用堆这种数据结构所涉及的一种排序算法,堆积是一个近似完全二叉树的结构,并满足堆积的性质:即子节点的键值或索引总是小于(或大于)它的父节点
function heapSort(array) {
    let length = array.length;
    for (let i = parseInt(array.length / 2) - 1; i >= 0; i--) {
        heap(array, i, length);
    }
    for (let j = length - 1; j >= 1; j--) {
        const temp = array[0];
        array[0] = array[j];
        array[j] = temp;
        heap(array, 0, --length);
    }
    return array;
}
function heap(array, x, length) {
    let l = 2 * x + 1, r = 2 * x + 2, largest = x;
    if (l < length && array[l] > array[largest]) {
        largest = l;
    }
    if (r < length && array[r] > array[largest]) {
        largest = r;
    }
    if (largest != x) {
        const temp = array[x];
        array[x] = array[largest];
        array[largest] = temp;
        heap(array, largest, length);
    }
}
  • 计数排序(Counting Sort)
    计数排序的核心在于输入的数据值转换为键存储在额外开辟的数组空间中,作为一种限行时间非要咋地的排序,计数排序要求输入的数据必须是由确定范围的整数。
    计数排序是一种很稳定的排序算法,需要用到一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数,然后根据数字C将A中的元素排到正确的位置上个,它只能对数组进行排序
function countSort(array) {
    const newArray = [], C = [];
    let min = array[0];
    let max = array[0];
    for (let i = 0; i < array.length; i++) {
        if (min >= array[i]) {
            min = array[i];
        }
        if (max <= array[i]) {
            max = array[i];
        }
        if (C[array[i]] = C[array[i]]) {
            C[array[i]]++;
        } else {
            C[array[i]] = 1;
        }
    }
    for (let j = min; j < max; j++) {
        C[j + 1] = (C[j + 1] || 0) + (C[j] || 0);
    }
    for (let k = array.length - 1; k >= 0; k--) {
        newArray[C[array[k]] - 1] = array[k];
        C[array[k]]--;
    }
    return newArray;
}
  • 桶排序(Bucket Sort)
    桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket sort)的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序

桶排序示意图.PNG

桶排序代码.jpg

  • 基数排序(Radix Sort)
    基数排序也是非比较的排序算法,对每一位进行排序,从最低位开始排序,复杂度为O(kn),为数组长度,k为数组中的数的最大的位数;基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。基数排序基于分别排序,分别收集,所以是稳定的。

基数排序代码.jpg

原文:https://www.jianshu.com/p/96f5c19e13df

原文地址:https://www.cnblogs.com/showcase/p/10716624.html

时间: 2024-09-29 10:03:59

十大经典排序算法的JS版的相关文章

十大经典排序算法(Javascript版)

1 冒泡排序 时间复杂度 O(n²) .额外空间复杂度O(1). 1)算法步骤 比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.这步做完后,最后的元素会是最大的数. 针对所有的元素重复以上的步骤,除了最后一个. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较. 2)动图演示 3)什么时候最快 当输入的数据已经是正序时,时间复杂度 O(n) . 4)什么时候最慢 当输入的数据是反序时,时间复杂度 O(n²) 

【转】十大经典排序算法

[转]十大经典排序算法:https://www.cnblogs.com/onepixel/articles/7674659.html 0.算法概述 0.1 算法分类 十种常见排序算法可以分为两大类: 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序. 非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序. 0.2 算法复杂度 0.3 相关概念 稳定:如果

十大经典排序算法(python实现)(原创)

经典排序算法图解: 经典排序算法的复杂度: 大类一(比较排序法): 1.冒泡排序(Bubble Sort) python代码实现: 1 d0 = [2, 15, 5, 9, 7, 6, 4, 12, 5, 4, 2, 64, 5, 6, 4, 2, 3, 54, 45, 4, 44] 2 d0_out = [2, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 9, 12, 15, 44, 45, 54, 64] # 正确排序 3 4 while 1: 5 stat

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

本文总结十大经典排序算法及变形,并提供Java实现. 参考文章: 十大经典排序算法总结(Java语言实现) 快速排序算法—左右指针法,挖坑法,前后指针法,递归和非递归 快速排序及优化(三路划分等) 一.排序算法概述 1.定义 将杂乱无章的数据元素,通过一定的方法按关键字顺序排列的过程叫做排序. 2.分类 十种常见排序算法可以分为两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序. 线性时间非比较类排序:不通过比较

python 十大经典排序算法

python 十大经典排序算法 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.常见的内部排序算法有:插入排序.希尔排序.选择排序.冒泡排序.归并排序.快速排序.堆排序.基数排序等.用一张图概括: 关于时间复杂度: 平方阶 (O(n2)) 排序 各类简单排序:直接插入.直接选择和冒泡排序. 线性对数阶 (O(nlog2n)) 排序 快速排序.堆排序和归并排序. O(n1+§)) 排序,§

十大经典排序算法(Python,Java实现)

参照:https://www.cnblogs.com/wuxinyan/p/8615127.html https://www.cnblogs.com/onepixel/articles/7674659.html 一.排序算法分类: 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序. 非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排 二.算法复杂度 注(

十大经典排序算法总结

前言 读者自行尝试可以想看源码戳这,博主在github建了个库,读者可以Clone下来本地尝试.此博文配合源码体验更棒哦~~~ 个人博客:Damonare的个人博客 原文地址:十大经典算法总结 这世界上总存在着那么一些看似相似但有完全不同的东西,比如雷锋和雷峰塔,小平和小平头,玛丽和马里奥,Java和javascript-.当年javascript为了抱Java大腿恬不知耻的让自己变成了Java的干儿子,哦,不是应该是跪舔,毕竟都跟了Java的姓了.可如今,javascript来了个咸鱼翻身,几

十大经典排序算法的算法描述和代码实现

这里详细讲解了十大经典算法的分类,例如交换排序.插入排序.选择排序等比较类排序,以及计数排序.桶排序和基数排序的非比较类排序,分析了各种排序算法的复杂度和稳定性,还有JAVA代码的详细实现.对冒泡排序.插入排序.选择排序和堆排序等十种算法进行了详细的思想总结. 一.算法概述 1.算法分类 十种常见排序算法可以分为两大类:(1)比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn)因此也称为非线性时间比较类排序.(2)非比较类排序:不通过比较元素间的相对次序,它可以突

Python十大经典排序算法

现在很多的事情都可以用算法来解决,在编程上,算法有着很重要的地位,将算法用函数封装起来,使程序能更好的调用,不需要反复编写. Python十大经典算法: 一.插入排序 1.算法思想 从第二个元素开始和前面的元素进行比较,如果前面的元素比当前元素大,则将前面元素 后移,当前元素依次往前,直到找到比它小或等于它的元素插入在其后面, 然后选择第三个元素,重复上述操作,进行插入,依次选择到最后一个元素,插入后即完成所有排序. 2.代码实现 1 def insertion_sort(arr): 2 #插入