算法01

1、冒泡排序

人们开始学习排序算法时,通常都先学冒泡算法,因为它在所有排序算法中最简单。然而, 从运行时间的角度来看,冒泡排序是最差的一个,接下来你会知晓原因。

冒泡排序比较任何两个相邻的项,如果第一个比第二个大,则交换它们。元素项向上移动至 正确的顺序,就好像气泡升至表面一样,冒泡排序因此得名。

冒泡排序算法的复杂度是 O(n²),并不推荐此算法。

Array.prototype.bubbleSort = function () {
    for (let i = 0; i < this.length; i++) {
        for (let j = 0; j < this.length - 1 - i; j++) {
            if (this[j] > this[j + 1]) {
                let tmp = this[j]
                this[j] = this[j + 1]
                this[j + 1] = tmp
            }
        }
    }
    return this
}

2、选择排序法

选择排序算法是一种原址比较排序算法。选择排序算法的思路是:找到数据结构中的最小值并

将其放置在第一位,接着找到第二小的值并将其放在第二位,以此类推。

 

其时间复杂度为 O(N^2)

虽然选择排序和冒泡排序的时间复杂度一样,但实际上,选择排序进行的交换操作很少,最多会发生 N - 1次交换。
而冒泡排序最坏的情况下要发生N^2 /2交换操作。从这个意义上讲,交换排序的性能略优于冒泡排序。
而且,交换排序比冒泡排序的思想更加直观。

Array.prototype.chooseSort = function () {

    for (let i = 0; i < this.length; i++) {
        let minIndex = i
        for (let j = i + 1; j < this.length; j++) {
            if (this[j] < this[i]) {
                minIndex = j
            }
        }
        let tmp = this[i]
        this[i] = this[minIndex]
        this[minIndex] = tmp
    }
    return this
}

3、插入排序

插人排序每次排一个数组项,以此方式构建最后的排序数组。假定第一项已经排序了,接着, 它和第二项进行比较,第二项是应该待在原位还是插到第一项之前呢?这样,头两项就已正确排 序,接着和第三项比较(它是该插人到第一、第二还是第三的位置呢?),以此类推。

Array.prototype.insertSort = function () {
    for (let i = 1; i < this.length; i++) {
        let j = i
        let tmp = this[j]
        while (j > 0 && this[j-1] > tmp) {
            this[j]=this[j-1]
            j--
        }
        this[j]=tmp
    }
    return this
}

4、归并排序

归并排序是第一个可以被实际使用的排序算法。前三个排序算法性能不好,但归并排序性能不错,其复杂度为O(n log^n)。

JavaScript的Array类定义了一个sort函数Array.prototype.sort用以排序JavaScript数组(我们不必自己实现这个算法)。ECMAScript没有定义用哪个排序算法,所以浏览器厂商可以自行去实现算法。例如,Mozilla Firefox 使用归并排序作为Array.prototype.sort的实现,而Chrome使用了一个快速排序的变体。

归并排序是一种分治算法。其思想是将原始数组切分成较小的数组,直到每个小数组只有一 个位置,接着将小数组归并成较大的数组,直到最后只有一个排序完毕的大数组。

由于是分治法,归并排序也是递归的:

Array.prototype.mergeSort = function () {
    function merge(left, right) {
        let res = []
        let indexL = 0
        let indexR = 0
        while (indexL < left.length && indexR < right.length) {
            if (left[indexL] > right[indexR]) {
                res.push(right[indexR])
                indexR++
            } else {
                res.push(left[indexL])
                indexL++
            }
        }
        while (indexR < right.length) {
            res.push(right[indexR])
            indexR++
        }
        while (indexL < left.length) {
            res.push(left[indexL])
            indexL++
        }
        return res
    }

    let apartArr = function (arr) {
        if (arr.length == 1) {
            return arr
        }
        let mid = Math.floor(arr.length / 2)
        let left = arr.slice(0, mid)
        let right = arr.slice(mid)

        return merge(apartArr(left),apartArr(right))//递归
    }
    return apartArr(this)
}

5)快速排序

快速排序也许是最常用的排序算法了。它的复杂度为O(nlog^n),且它的性能通常比其他的复杂度为O(nlog^n)的排序算法要好。和归并排序一样,快速排序也使用分治的方法,将原始数组分为较小的数组(但它没有像归并排序那样将它们分割开)。

快速排序的基本过程:

  1. 首先,从数组中选择中间一项作为主元
  2. 创建两个指针,左边一个指向数组第一个项,右边一个指向数组最后一个项。移动左指 针直到我们找到一个比主元大的元素,接着,移动右指针直到找到一个比主元小的元素,然后交 换它们,重复这个过程,直到左指针超过了右指针。这个过程将使得比主元小的值都排在主元之 前,而比主元大的值都排在主元之后。这一步叫作划分操作。
  3. 接着,算法对划分后的小数组(较主元小的值组成的子数组,以及较主元大的值组成的 子数组)重复之前的两个步骤,直至数组已完全排序。
Array.prototype.quickSort = function() {
    const partition = (array, left, right) => {
        var pivot = array[Math.floor((right + left) / 2)]
        let i = left
        let j = right
        while (i <= j) {
            while (array[i] < pivot) {
                i++
            }
            while (array[j] > pivot) {
                j--
            }
            if (i <= j) {
                let aux = array[i]
                array[i] = array[j]
                array[j] = aux
                i++
                j--
            }
        }
        return i
    }
    const quick = (array, left, right) => {
        let index
        if (array.length > 1) {
            index = partition(array, left, right)
            if (left < index - 1) {
                quick(array, left, index - 1)
            }
            if (index < right) {
                quick(array, index, right)
            }
        }
    }
    quick(this, 0, this.length - 1)
    return this
}
原文地址:https://www.cnblogs.com/Tanqurey/p/10724412.html