排序算法总结(JavaScript版)

在排序的过程中,若整个文件都是放在内存中处理,排序时不涉及内外存的数据交换,则成为内排序;返回,如果在排序的过程中要进行内外存数据交换,则称之为外排序。
按策略划分内排序分为五类:插入排序、选择排序、交换排序、归并排序和分配排序。本文暂且介绍前三种排序算法,后两种在不久后更新。
一、插入排序
插入排序的基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排序好的适当位置,知道全部记录插入完为止。本文介绍两种插入排序方法。

  1. 直接插入排序
    时间复杂度:O(n^2)
// 直接插入排序
function InsertSort(R) {
    for (let i = 1; i < R.length; i++) {
        if (R[i] < R[i - 1]) {
            let temp = R[i]
            let j = 0
            for (j = i - 1; j >= 0 && temp < R[j]; j--) {
                R[j + 1] = R[j]
            }
            R[j + 1] = temp
        }
    }
}

直接插入排序示意图

  1. 希尔排序
    希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
    时间复杂度:O(n(log2n)^2)
// 希尔排序 
// 由于希尔排序法是按增量分组进行的排序,所以希尔排序是不稳定的排序;
// 其适用于中等规模的记录序列的排序情况
// increment为增量数组,d为当前增量,增量数组应为递减数组,最后增量应为1
function ShellSort(R, increment) {
    let i, j, temp, d
    for (let m = 0; m < increment.length; m++) {
        d = increment[m]
        for (i = d; i < R.length; i++) {
            if (R[i] < R[i - d]) {
                temp = R[i]
                j = i - d
                do {
                    R[j + d] = R[j]
                    j = j - d
                } while (j > 0 && temp < R[j])
                R[j + d] = temp
            }
        }
    }
}

希尔排序示意图
二、选择排序
选择排序的基本思想是:每一趟从待排序的记录上选出关键字最小的记录,顺序放在已排序好的最后,直到全部记录排序完毕。
直接选择排序
时间复杂度:O(n^2)

// 直接选择排序
// 不稳定
function SelectSort(R) {
    let i, j, k, temp
    for (i = 0; i < R.length - 1; i++) {
        k = i
        for (j = i + 1; j < R.length; j++) {
            if (R[j] < R[k]) {
                k = j
            }
        }
        if (k != i) {
            temp = R[i]
            R[i] = R[k]
            R[k] = temp
        }
    }
}

直接选择排序示意图
三、交换排序
交换排序的基本思想是:两两比较待排序记录的关键字,发现两个记录的次序相反时即进行交换,知道没有反序的记录为止。

  1. 冒泡排序
    冒泡排序算法的原理如下:
    1、比较相邻的元素。如果第一个比第二个大,就交换他们两个。
    2、对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
    3、针对所有的元素重复以上的步骤,除了最后一个。
    4、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
    时间复杂度:O(n^2)
// 冒泡排序
function BubbleSort(R) {
    let i, j, exchange, tmp, n = R.length
    for (i = 1; i < n; i++) {
        exchange = false // 本趟排序开始前,交换标注为假
        for (j = 0; j < n - 1; j++) {
            if (R[j] > R[j + 1]) {
                tmp = R[j + 1]
                R[j + 1] = R[j]
                R[j] = tmp
                exchange = true // 发生了交换,故将交换标志置为真
            }
        }
        if (!exchange) {
            return // 本趟排序未发生交换,终止算法
        }
    }
}

在这里插入图片描述

  1. 快速排序
    一趟快速排序的算法是:
    1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
    2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];
    3)从j开始向前搜索,即由后开始向前搜索(j–),找到第一个小于key的值A[j],将A[j]和A[i]互换;
    4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;
    5)重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。
    时间复杂度:O(nlog2n)
// 快速排序
// 调用时将low设置为0,high设置为R的长度-1
//  不稳定。(稳定与否取决于能不能保证数组的原有顺序)
function QuickSort(R, low, high) {
    if (low > high) {
        return
    }
    let pivot = R[low]
    let i = low
    let j = high
    let temp
    while (i < j) {
        while ((i < j) && (R[i] <= pivot)) {
            ++i
        }
        while ((j >= i) && (R[j] >= pivot)) {
            --j
        }
        if (i < j) {
            temp = R[i]
            R[i] = R[j]
            R[j] = temp
        }
    }
    if (low < j) {
        temp = R[low]
        R[low] = R[j]
        R[j] = temp
    }
    QuickSort(R, low, j - 1)
    QuickSort(R, j + 1, high)
}

一趟快速排序示意图

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值