IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构与算法基础知识(三):常见排序、搜索算法 -> 正文阅读

[数据结构与算法]数据结构与算法基础知识(三):常见排序、搜索算法

系列文章

数据结构与算法基础知识(一):时间复杂度和空间复杂度
数据结构与算法基础知识(二):常见数据结构
数据结构与算法基础知识(三):常见排序、搜索算法


前言

本篇介绍一些比较常见的排序算法与搜索算法。

  • 排序:把某个乱序的数组变成升序或者降序的数组。
  • 搜索:找出数组中某个元素的下标。

冒泡排序

思路:

  • 两两比较arr数组中所有相邻元素,如果前一个比后一个大,则交换它们;
  • 一轮下来,可以保证最后一个数是最大的;
  • 执行arr.length - 1轮,就可以完成排序。

演示:

代码:

function swap(arr, i, j) {
    const temp = arr[i]
    arr[i] = arr[j]
    arr[j] = temp
}

function bubbleSort(arr) {
    for (let i = 0; i < arr.length - 1; i++) {
        let didSwap = false
        for (let j = 0; j < arr.length - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                swap(arr, j, j + 1)
                didSwap = true
            }
        }
        if (!didSwap) break
    }
}

复杂度:

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2)
  • 空间复杂度: O ( 1 ) O(1) O(1)

选择排序

思路:

  • 找到数组中的最小值,与数组第一个元素进行交换;
  • 找到数组中第二小的值,与数组第二个元素进行交换;
  • 以此类推,执行arr.length - 1轮。

演示:

代码:

function swap(arr, i, j) {
    const temp = arr[i]
    arr[i] = arr[j]
    arr[j] = temp
}

function selectionSort(arr) {
    for (let i = 0; i < arr.length - 1; i++) {
        let idMin = i
        for (let j = i; j < arr.length; j++) {
            if (arr[j] < arr[idMin]) idMin = j
        }
        if (idMin !== i) swap(arr, i, idMin)
    }
}

复杂度:

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2)
  • 空间复杂度: O ( 1 ) O(1) O(1)

插入排序

思路:

  • 数组第二个元素与前面的元素比较,遇到比它大就排它后面。
  • 数组第三个元素与前面的元素比较,遇到比它大就排它后面。
  • 以此类推,执行arr.length - 1轮。

演示:

代码:

function insertionSort(arr) {
    for (let i = 1; i < arr.length; i++) {
        const temp = arr[i]
        let j
        for (j = i; j > 0 && arr[j - 1] > temp; j--) {
            arr[j] = arr[j - 1]
        }
        arr[j] = temp
    }
}

复杂度:

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2)
  • 空间复杂度: O ( 1 ) O(1) O(1)

希尔排序

思路:

  • 根据数组长度得到间隔大小,按照间隔对数组进行分组,各组内部进行插入排序;
  • 缩小间隔大小,按照间隔对数组进行分组,各组内部进行插入排序;
  • 以此类推,当间隔缩小为1,对数组整体进行插入排序。

演示:

代码:

function shellSort(arr) {
    let interval = arr.length >> 1
    while (interval >= 1) {
        for (let i = interval; i < arr.length; i++) {
            let temp = arr[i]
            let j
            for (j = i; j - interval >= 0 && arr[j - interval] > temp; j -= interval) {
                arr[j] = arr[j - interval]
            }
            arr[j] = temp
        }
        interval = interval >> 1
    }
}

复杂度:

  • 时间复杂度: O ( n 1.3 ) O(n^{1.3}) O(n1.3)~ O ( n 2 ) O(n^2) O(n2)
  • 空间复杂度: O ( 1 ) O(1) O(1)

归并排序

思路:

  • 把数组分为左右两个子数组,再对各个子数组进行同样操作(递归),直到每个子数组只包含一个数组元素;
  • 把两个子数组合并为一个有序数组,再对合并后的数组进行同样操作(递归),直到全部子数组合并为一个完整有序数组。

演示:

代码:

function mergeSort(arr) {
    if (arr.length === 1) return arr

    const mid = arr.length >> 1
    const left = arr.slice(0, mid)
    const right = arr.slice(mid)

    const resLeft = mergeSort(left)
    const resRight = mergeSort(right)

    const res = []

    while (resLeft.length || resRight.length) {
        if (resLeft.length && resRight.length) {
            res.push(resLeft[0] < resRight[0] ? resLeft.shift() : resRight.shift())
        } else if (resLeft.length) {
            res.push(resLeft.shift())
        } else if (resRight.length) {
            res.push(resRight.shift())
        }
    }

    return res
}
// 未改变原数组

复杂度:

  • 时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
  • 空间复杂度: O ( n ) O(n) O(n)

快速排序

思路:

  • 定义一个快排函数,先从数组中选取一个支点pivot,快排函数执行完毕后会将数组分为左右两个部分,左半部分所有元素的值小于等于支点pivot,右半部分所有元素的值大于等于支点pivot;
  • 对左右两个部分分别调用快排函数(递归)。

演示:

代码:

function quickSort(arr, left, right) {
    if(!arr) return
    left = left === undefined ? 0 : left
    right = right === undefined ? arr.length - 1 : right
    if(!(left < right)) return

    let i = left - 1, j = right + 1
    const pivot = arr[(left + right) >> 1]

    while (i < j) {
        do {i++} while (arr[i] < pivot)
        do {j--} while (arr[j] > pivot)
        if (i < j) { // 如果 i < j,交换 arr[i] 和 arr[j] 的值
            const temp = arr[i]
            arr[i] = arr[j]
            arr[j] = temp
        }
    }

    quickSort(arr, left, j)
    quickSort(arr, j + 1, right)
}

复杂度:

  • 时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
  • 空间复杂度: O ( l o g n ) O(logn) O(logn)

顺序搜索

思路:

  • 遍历数组;
  • 若找到跟目标值相等的元素,则返回它的下标;
  • 如果遍历完数组后没有找到跟目标值相等的元素则返回-1

演示:

代码:

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

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

二分搜索

思路:
适用于已经完成排序的有序数组。

  • 二分搜索查找数组中间元素;
  • 如果中间元素大于目标值,则对中间元素的左半部分进行二分搜索,否则对中间元素的右半部分进行二分搜索。

演示:

代码:

function binarySearch(arr, target) {
    let l = 0, r = arr.length - 1
    while (l <= r) {
        const m = (l + r) >> 1
        if (arr[m] < target) l = m + 1
        else if (arr[m] > target) r = m - 1
        else return m
    }
    return -1
}

复杂度:

  • 时间复杂度: O ( l o g n ) O(logn) O(logn)
  • 空间复杂度: O ( 1 ) O(1) O(1)

至此,常见的排序算法与搜索算法就介绍完了。创作不易,希望多多支持~~

如有疏漏之处欢迎评论区留言指正~~

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-06-01 15:26:10  更:2022-06-01 15:28:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:42:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码