博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript数据结构与算法(排序算法)
阅读量:6267 次
发布时间:2019-06-22

本文共 4522 字,大约阅读时间需要 15 分钟。

比较排序算法一般有三个指标

  • 时间复杂度, 算法执行完成所需要的时间
  • 空间复杂度, 算法执行完成所需要的空间
  • 稳定性,当二个元素的值相同的时候,排序之后二个元素的前后位置是否发生改变

以下的排序都为升序

冒泡排序

冒泡排序是面试官最喜欢问新手程序员的.冒泡排序就像名字一样,冒泡排序第一次冒出最大的,第二次冒出第二大的,第三次冒出第三大的.....直到冒出倒数第二大的.

const array = [12, 2, 3, 10, 8, 8, 9, 21]function BubbleSort(array){    let len = array.length;    if (len == 0 || len == 1) {        return array;    }    for (let i = 0; i < len-1; i++) {        for (let j = 0; j < len-1-i; j++) {  // 减i是因为第0到第i大已经冒出来了 不需要再比较了            if (array[j] > array[j+1]) {                [array[j], array[j+1]] = [array[j+1], array[j]];            }        }    }    return array}BubbleSort(array)  //[2, 3, 8, 8, 9, 10, 12, 21]复制代码

时间复杂度为O(n^2),空间复杂度为O(1),稳定

仅仅面试考察,实际运用是不会用到的,因为冒泡排序是非常没效率的,因为不仅时间复杂度高而且有O(n^2)的交换,交换所耗的性能远大于比较

选择排序

选择排序是第一位找到最小的,第二位找到第二小的,第三位找到第三小的.....

const array = [12, 2, 3, 10, 8, 8, 9, 21]function SelectionSort(array){    let len = array.length;    if (len == 0 || len == 1) {        return array;    }    for (let i = 0; i < len-1; i++) {        let min = i;        for (let j = i+1; j < len-1-i; j++) {            if (array[j] < array[min]) {                min = j            }        }        [array[i], array[min]] = [array[min], array[i]];    }    return array }SelectionSort(array)  //[2, 3, 8, 8, 9, 10, 12, 21]复制代码

时间复杂度为O(n^2),空间复杂度为O(1),稳定

仅仅面试考察,实际运用跟冒泡一样,也不会用到,因为效率也非常低. 但是比冒泡好点,因为元素如果再正确的位置上不会交换。

插入排序

就是,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入

const array = [12, 2, 3, 10, 8, 8, 9, 21]function InsertionSort(array){        let len = array.length;        if (len == 0 || len == 1) {            return array;        }        for (let i = 1; i < len; i++) {            for (let j = 0; j < i; j++) {        // 查找的部分可以使用二分查找                if (array[j] > array[i]) {                    this.splice(j, 0, array[i]); // 插入进来                    this.splice(i+1, 1);         // 删除已插入的元素                     break;                }            }        }        return array;    }InsertionSort(array)  //[2, 3, 8, 8, 9, 10, 12, 21]复制代码

时间复杂度为O(n^2),空间复杂度为O(1),不稳定

效率也不高,通常也不会使用,但是如果数据接近线性排列.那么使用二分查找插入排序是一个非常好的选择

快速排序

这个也是经常被问到,是递归算法的经典使用场景

const array = [12, 2, 3, 10, 8, 8, 9, 21]function quickSort(array){    let len = array.length;    if (len == 0 || len == 1) {        return array;    }    let mid = array[0],        left =[],        right = [];    for (let i = 1; i < len; i++) {        if (array[i] < mid) {            left.push(array[i])        } else {            right.push(array[i])        }    }    return quickSort(left).concat(mid, quickSort(right))}quickSort(array)  //[2, 3, 8, 8, 9, 10, 12, 21]复制代码

时间复杂度为O(nlogn),空间复杂度为O(n),不稳定

平均时间复杂度低 ,占用空间小,快速排序是使用得最多得排序算法

归并排序

归并排序是分治算法得经典应用,归并算法得核心是将两个已经排序的序列合并成一个序列.

const array = [12, 2, 3, 10, 8, 8, 9, 21]function mergeSort(array){    let len = array.length;    if (len == 0 || len == 1) {        return array;    }    function merge(left, right) {        let final = [];        while (left.length && right.length) {            final.push(left[0] <= right[0] ? left.shift() : right.shift());        }		return final.concat(left.concat(right));    }    let mid = Math.floor(len-1/2);    let left = array.slice(0, mid)    let right = array.slice(mid);    return merge(mergeSort(left), mergeSort(right))}mergeSort(array)  //[2, 3, 8, 8, 9, 10, 12, 21]复制代码

时间复杂度为O(nlogn),空间复杂度为O(n),不稳定

时间复杂度和空间复杂度与快速排序是一样的,其实二个性能是相当的,毕竟二种排序都出现在浏览器内核中。为什么要快速排序使用较大,可能快速排序在各种数据量下表现得更为稳定吧. 但是如果数据呈分段有序时,使用归并排序效率更高

堆排序

具体如何实现,在这一章已经讲过,我直接贴上代码了

// 最大堆调整  function maxHeapfiy(array, i, heapSize){        let left = 2*i+1,            right = 2*i+2,            mid = i;        if (left < heapSize && array[left] > array[mid]) {            mid = left;        }        if (right < heapSize && array[right] > array[mid]) {            mid = right;        }        if (mid != i) {            [array[i], array[mid]] = [array[mid], array[i]]            maxHeapfiy(array, mid, heapSize)        }    }      // 构建最大堆    const buildMaxHeapfiy = (array, heapSize) => {        let parent = Math.floor(heapSize/2)        for (parent; parent >= 0; parent--) {            maxHeapfiy(array, parent, heapSize)        }    }        // 堆排序    const array = [12, 2, 3, 10, 8, 8, 9, 21];    let heapSize = array.length;    buildMaxHeapfiy(array, heapSize)    for (let i = heapSize-1; i >=0; i--) {        [array[0], array[i]] = [array[i], array[0]];        this.maxHeapfiy(array, 0, i);    }    // [2, 3, 8, 8, 9, 10, 12, 21]复制代码

时间复杂度为O(nlogn),空间复杂度为O(n),不稳定

堆排序虽然,时间复杂度和空间复杂度都较低,但是堆排序的有个缺点在于当堆中的一个数据发生改变,都需要进行堆调整来维护最大堆(最小堆),需要额外的维护开销,由于在实际运用中,数据变动是很频繁的,所以实际上堆排序不是很适合实际的运用。

转载地址:http://ywcpa.baihongyu.com/

你可能感兴趣的文章
poj2367 拓扑序
查看>>
C++中的集合和字典
查看>>
自动化管理之新人培养
查看>>
linux 文件上传&软件安装(rpm)
查看>>
iOS 12 越狱支持 Cydia
查看>>
Android中远程Service浅析
查看>>
面向对象的标准库(续)
查看>>
scrollHieght、offsetHeight、clientHeight、width、height
查看>>
面向对象 三大特性
查看>>
Tomcat配置Web默认页面
查看>>
idea phpstorm webstorm等的配置问题
查看>>
bzoj 3501 PA2008 Cliquers Strike Back——贝尔数
查看>>
数据输入验证---Silverlight商业应用程序开发学习笔记(13)
查看>>
SQL SERVER读书笔记:TempDB
查看>>
2016.7.17
查看>>
2016.7.19
查看>>
习题6-3 UVa536 Tree Recovery(树的遍历转换)
查看>>
jquery源码解析:jQuery原型方法init的详解
查看>>
skyeye下修改uboot支持2410从nand启动
查看>>
MyTT工作(一)ListView使用
查看>>