JavaScript中常用的排序和搜索

​​​​​​​目录

排序

1.sort排序

实现代码:

2.冒泡排序

原理:

执行流程:

实现代码:

3.选择排序

原理:

执行流程:

实现代码:

4.插入排序

原理:

执行流程:

实现代码:

5.归并排序

原理:

执行流程:

实现代码:

6.快速排序

原理:

执行流程:

实现代码:

搜索 

1.二分搜索

原理:

执行流程:

注意:

实现代码:

2.顺序搜索

原理:

执行流程:

实现代码:


排序

1.sort排序

在 JavaScript 中,sort函数是对数组进行排序的常用函数。sort函数采用了一种基于比较的排序算法,具体来说,它通过比较数组中的元素,根据排序规则将它们排成相应的顺序。

在默认情况下,sort函数会将数组中的元素转化为字符串,然后根据其 Unicode 编码值进行升序排序。例如,[20, 3, 12].sort() 的结果为 [12, 20, 3],因为这三个数字转化为字符串后,它们的编码值分别是 "12"、"20" 和 "3",按照 Unicode 编码值的升序排列,就是 ["12", "20", "3"]。

为了实现自定义的排序规则,sort函数接受一个比较函数作为参数。比较函数接受两个参数 a 和 b,分别表示数组中的两个元素,需要返回一个数值来指示它们的相对位置。如果返回值大于 0,则表示 a 在 b 后面;如果返回值小于 0,则表示 a 在 b 前面;如果返回值等于 0,则表示 a 和 b 在排序后保持原来的相对位置。

根据传入的比较函数不同,sort函数会使用不同的排序算法。在 V8 引擎中,sort函数会根据输入数组的大小和类型,选择使用快速排序或归并排序。当输入数组大小小于某个特定值时,sort函数会使用插入排序。

需要注意的是,sort函数在排序过程中会修改原始数组,因此需要在必要的情况下先创建原数组的一个副本再进行排序。

实现代码:

const numbers = [1, 3, 2, 10, 5]
numbers.sort() // [1, 10, 2, 3, 5]

// 按照数值大小排序
numbers.sort((a, b) => a - b) // [1, 2, 3, 5, 10]

// 按照数值大小的反向排序
numbers.sort((a, b) => b - a) // [10, 5, 3, 2, 1]

2.冒泡排序

原理:

比较相邻的两个元素大小,如果前一个元素比后一个元素大,就交换这两个元素的位置,不断地重复这个过程,直到整个序列按照从小到大的顺序排列。

执行流程:

1.比较所有的相邻元素,如果第一个比第二个大,就交换他们

2.一轮下来,就可以保证最后一个元素是最大的

3.执行n-1轮,即可完成排序

实现代码:

const Fn = (arr) => {
    for (let i = 0; i < arr.length - 1; i++) {
        for (let j = 0; j < arr.length - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                const temp = arr[j]
                arr[j] = arr[j + 1]
                arr[j + 1] = temp
            }
        }
    }
    return arr
}
Fn([5, 8, 9, 1, 3, 6, 99]) // Array(7) [1,3,5,6,8,9,99]

3.选择排序

原理:

从未排序的序列中选择最小(或最大)的元素,将其排在已排序序列的头部/末尾,不断重复这个过程,直到所有元素都排序完成。

执行流程:

1.找到数组中的最小值,放到数组的第一位
2.找到数组的第二小的值,放到数组的第二位
3.依次类推,执行n-1轮

实现代码:

const selectionSort = (arr) => {
    for (let i = 0; i < arr.length; i++) {
        let minIndex = i
        for (let j = i; j < arr.length; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j
            }
        }
        if (minIndex !== i) {
            const temp = arr[i]
            arr[i] = arr[minIndex]
            arr[minIndex] = temp
        }
    }
    return arr
}
selectionSort([6, 4, 2, 9, 1, 12, 3, 65, 963, 1024, 999]) //[1,2,3,4,6,9,65,963,999,1024]

4.插入排序

原理:

将未排序序列的元素插入已排序序列中正确的位置,使得已排序的序列仍然有序。

执行流程:

1.从第二个数开始往前比较,比它大的话就往后排
2.以此类推,进行到最后一个数

实现代码:


const insertionSort = (arr) => {
    for (let i = 1; i < arr.length; i++) {
        let temp = arr[i];
        let j = i;
        while (j > 0) {
            if (temp < arr[j - 1]) {
                arr[j] = arr[j - 1];
            } else {
                break;
            }
            j--;
        }
        arr[j] = temp;
    }
    return arr
}
insertionSort([4, 6, 9, 21, 3, 6, 99, 255, 1024, 1])  // Array(10) [1,3, 4, 6, 6, 9, 21, 99, 255, 1024]

5.归并排序

原理:

归并排序(Merge Sort)是一种分治算法,其核心思想是将一个待排序序列分成两个子序列,对每个子序列进行递归排序,然后将两个已排序的子序列合并成一个有序序列。

执行流程:

1.从数组的中间进行劈开,一分为二
2.然后递归的对子数组进行分的操作,直到分成一个个单独的数
3.把两个数合并成有序数组,再对有序数组进行合并,直到合并成一个完整的有序数组

实现代码:

Array.prototype.mergeSort = () => {
    const rec = (arr) => {
        if (arr.length === 1) return arr
        const mid = Math.floor((arr.length) >> 1)
        const left = arr.slice(0, mid)
        const right = arr.slice(mid, arr.length)
        const orderLeft = rec(left)
        const orderRight = rec(right)
        const res = []
        while (orderLeft.left || orderRight.length) {
            if (orderLeft.length && orderRight.length) {
                res.push(orderLeft[0] < orderRight[0] ? orderLeft.shift() : orderRight.shift())
            } else if (orderLeft.length) {
                res.push(orderLeft.shift())
            } else if (orderRight.length) {
                res.push(orderRight.shift())
            }
        }
        return res
    }
    const ans = rec(this)
    ans.forEach((item, index) => {
        this[index] = item
    })
}
const arr = [6, 9, 2, 4, 3, 69, 99, 1024, 999]
arr.mergeSort(arr)

6.快速排序

原理:

快速排序(Quick Sort)也是一种分治算法,其核心思想是通过选取一个基准值,将待排序序列分成两个子序列,其中一个序列中的所有元素都小于基准值,另一个序列中的所有元素都大于等于基准值,然后对两个子序列分别递归进行快速排序。

执行流程:

1.分区:选择一个基准,比基准大的放到基准的后面,比基准小的放到基准的前面
2.递归:递归的对基准前后的子数组进行分区

实现代码:

Array.prototype.fastSort = function () {
    const rec = (arr) => {
        if (arr.length === 1) {
            return arr;
        }
        const left = []
        const right = []
        const standard = arr[0]
        for (let i = 1; i < arr.length; i++) {
            if (arr[i] < standard) {
                left.push(arr[i])
            } else {
                right.push(arr[i])
            }
        }
        return [...rec(left), standard, ...rec(right)]
    }
    const res = rec(this)
    res.forEach((item, index) => {
        this[index] = item
    })
}
const arr = [6, 2, 5, 8, 9, 9, 23, 69]
arr.fastSort(arr)

搜索 

1.二分搜索

原理:

采用分治策略,将要查找的键值与数组的中间元素进行比较,然后根据结果选择继续在左半部分或右半部分进行查找,直到找到要查找的元素或者确定要查找的元素不在数组中为止。

执行流程:

1.从数组的中间元素开始,如果中间元素正好是目标值,则搜索结束。
2.如果目标值大于或者小于中间元素,则在大于或小于中间元素的那一半数组中搜索

注意:

使用二分搜索的前提是这个数组是排好序的,如果没有排好序的话,使用sort方法先将数组排好序

实现代码:

Array.prototype.binarySearch = function (target) {
    let min = 0
    let max = this.length - 1
    while (min <= max) {
        let middle = Math.floor((min + max) / 2)
        let element = this[middle]
        if (target > element) {
            min = middle + 1
        } else if (target < element) {
            max = middle - 1
        } else {
            return middle
        }
    }
    return -1
}

const arr = [1, 2, 3, 4, 5, 6].binarySearch(6)

2.顺序搜索

原理:

从数组的第一个元素开始,逐个遍历数组中所有的元素,直到找到要查找的元素或者确定要查找的元素不在数组中。

执行流程:

1.遍历数组。
2.找到跟目标值相等的元素,就返回它的下标
3.遍历结束后,如果没有搜索到目标值,就返回-1

实现代码:

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

const arr = [6, 9, 5, 2, 7, 99].sequentialSearch(99)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值