• 十大排序详解


     冒泡排序(n2)

    第一层循环遍历外层 length -1个项,对前length-1 个数排序

    内层循环遍历到length - i -1,对前length - i -1个数冒泡

    1. function bubbleSort(arr) {
    2. for (let i = 0; i < arr.length - 1; i++) {
    3. for (let j = 0; j < arr.length - i - 1; j++) {
    4. const temp = arr[j + 1]
    5. arr[j + 1] = arr[j]
    6. arr[j] = temp
    7. }
    8. }
    9. }

    选择排序(n2)

    从乱序区中选择最小加入顺序区

    外层循环:扩展乱序区域到length-1

    内层循环:选择乱序区域中最小下标

    1. function selectSort(arr) {
    2. for (let i = 0; i < arr.length - 1; i++) {
    3. let minIndex = i
    4. for (let j = i + 1; j < arr.length; j++) {
    5. if (arr[j] < arr[minIndex]) {
    6. minIndex = j
    7. }
    8. }
    9. const tmp = arr[i];
    10. arr[i] = arr[minIndex];
    11. arr[minIndex] = tmp;
    12. }
    13. }

    插入排序(n2)

    从乱序区中随便选一个,找到其在乱序区域中的位置

    外层循环 :扩展有序区域,到length-1

    内层循环:在有序区中找到插入的位置

    用pre和current辅助寻找位置

    1. function insertionSort(arr) {
    2. for (let i = i; i < arr.length - 1; i++) {
    3. let preIndex = i - 1
    4. let current = arr[i]
    5. while (preIndex > 0 && arr[preIndex] > current) {
    6. arr[preIndex + 1] = arr[preIndex]
    7. preIndex--
    8. }
    9. }
    10. arr[preIndex + 1] = current
    11. }

    希尔排序(nlogn~nlog2n)

    用gap将数组拆分,每一小数组再进行插入排序

    外外层循环:gap每次折一半,直至gap为0

    1. function shellSort(arr) {
    2. for (let gap = Math.floor(arr.length); gap > 0; gap = Math.floor(arr / 2)) {
    3. for (let i = gap; gap < arr.length; i++) {
    4. const curr = arr[i]
    5. let j = i
    6. while (j - gap > 0 && arr[j-gap] >curr) {
    7. arr[j]=arr[j-gap]
    8. j=j-gap
    9. }
    10. arr[j]=curr
    11. }
    12. }
    13. }

    归并排序(nlogn)

    标准分治法,划分为两个数组,递归解决。

    1. function mergeSort(arr) {
    2. function sort(arr, left, right) {
    3. if (left < right) {
    4. const mid = (left + right) / 2
    5. leftArr = sort(arr, left, mid)
    6. rightArr = sort(arr, mid + 1, right)
    7. return merge(leftArr, rightArr)
    8. }
    9. return left > 0 ? [arr[left]] : []
    10. }
    11. function merge(leftArr, leftArr) {
    12. const res = []
    13. const leftPtr = 0
    14. const rightPtr = 0
    15. while (leftPtr < leftArr.length && rightPtr < rightArr.length) {
    16. if (leftArr[leftPtr] < leftArr[rightPtr]) {
    17. res.push(leftArr[leftPtr++])
    18. } else {
    19. res.push(rightArr[rightPtr++])
    20. }
    21. }
    22. while (leftPtr < leftArr.length) {
    23. res.push(leftArr[leftPtr++])
    24. }
    25. while (rightPtr < rightArr.length) {
    26. res.push(rightArr[rightPtr++])
    27. }
    28. return res
    29. }
    30. }

    快速排序(nlogn-n2)

    分治法,选取首个元素,将数组分为大于元素的一组和小于元素的一组。递归解决

    主要包括四个步骤

    后往前,找比x小

    交换

    前往后,找比x大

    交换

    1. function quickSort(arr) {
    2. function sort(arr, low, high) {
    3. let i = low
    4. let j = high
    5. const x = arr[low]
    6. while (i < j) {
    7. while (i < j && arr[j] > x) {
    8. j--
    9. }
    10. if (i < j) {
    11. arr[i] = arr[j]
    12. i++
    13. }
    14. while (i < j && arr[i] < x) {
    15. i++
    16. }
    17. if (i < j) {
    18. arr[j] = arr[i]
    19. j--
    20. }
    21. }
    22. arr[i] = x
    23. sort(arr, low, i - 1)
    24. sort(arr, i + 1, high)
    25. }
    26. }

    计数排序(n+k)

    确定数组范围,开辟连续的空间,一次存储,按照空间顺序读取

    类似哈希表,将下标作为数值存入

    1. // 计数排序
    2. function countingSort(arr) {
    3. let maxValue = Number.MIN_VALUE
    4. let minValue = Number.MAX_VALUE
    5. const res = []
    6. // 确定空间
    7. arr.forEach(num => {
    8. maxValue = num > maxValue ? num : maxValue
    9. minValue = num > minValue ? minValue : num
    10. })
    11. if (minValue < 0) {
    12. offset = -minValue
    13. }
    14. const bucket=new Array(maxValue+offset+1).fill(0)
    15. // 存入对应下标
    16. arr.forEach(num=>{
    17. bucket[num+offset]++
    18. })
    19. bucket.forEach((store,index)=>{
    20. while(store--){
    21. res.push(index-offset)
    22. }
    23. })
    24. return result
    25. }

    基数排序

    对每一位放入不同的桶中

    堆排序

     大顶堆:根节点比孩子都大

    1、前置函数,维护大顶堆的性质

    交换根节点与最大值

    递归维护被交换结点的性质

     2、构建大顶堆

    从第一个叶子节点的父节点开始:n - 2 / 2 = n / 2 - 1

    遍历每一个节点,进行性质维护

    3、排序

    将头部与尾部交换

    然后断开尾部连接

    维护大顶堆

    此时尾部为最大

     

  • 相关阅读:
    Mybatis简介
    MobaXterm工具使用/Docker安装Redis/Redisinsight工具使用
    对于可变参数的处理
    leetcode1769:移动所有球到每个盒子所需的最小操作数(12.2日每日一题)
    学C的第二十二天【深度剖析数据在内存中的存储:1. 数据类型介绍;2. 整型在内存中的存储】
    R语言根据日历周期处理时间序列数据(周、月、年等):使用xts包的apply.monthly函数和mean函数计算时间序列的月平均值(monthly)
    QT7_视频知识点笔记_3_自定义控件,事件处理器⭐,定时器,QPainter,绘图设备,不规则窗口
    一日一技:用Python绘画有多好玩
    强化记忆的七种武器
    【Bluetooth|蓝牙开发】一、开篇词 | 打造全网最详细的Bluetooth开发教程
  • 原文地址:https://blog.csdn.net/qq_46222031/article/details/125904620