七大 排序算法(一篇文章梳理)

一、引言

排序算法是计算机科学中不可或缺的一部分,它们在数据处理、数据库管理、搜索引擎、数据分析等多个领域都有广泛的应用。排序算法的主要任务是将一组数据元素按照某种特定的顺序(如升序或降序)进行排列。本文将对一些常见的排序算法进行详细的介绍和分析,包括冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序等。

二、排序算法的分类

排序算法大致可以分为以下几类:

1 比较排序

基于比较的排序算法通过比较元素的大小来决定它们的顺序。常见的比较排序算法有冒泡排序、选择排序、插入排序、归并排序、快速排序等。

2 非比较排序

非比较排序算法不依赖于元素之间的比较,而是利用一些特定的属性或规则来排序。常见的非比较排序算法有计数排序、基数排序、桶排序等。

3 稳定排序

稳定排序算法在排序过程中,如果两个元素相等,它们在排序后的相对位置不会改变。常见的稳定排序算法有冒泡排序、插入排序、归并排序等。

4 不稳定排序

不稳定排序算法在排序过程中,如果两个元素相等,它们在排序后的相对位置可能会改变。常见的不稳定排序算法有选择排序、快速排序、堆排序等。

三、常见排序算法详解

1 冒泡排序(Bubble Sort)

冒泡排序是一种简单的排序算法,它重复地遍历待排序的序列,一次比较两个相邻的元素,如果它们的顺序错误就把它们交换过来。遍历序列的工作是重复地进行直到没有再需要交换,也就是说该序列已经排序完成。

时间复杂度:O(n^2)

空间复杂度:O(1)

def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        for j in range(0, n - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    return arr

2 选择排序(Selection Sort)

选择排序是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。

时间复杂度:O(n^2)

空间复杂度:O(1)

def selection_sort(arr):
    for i in range(len(arr)):
        min_index = i
        for j in range(i+1, len(arr)):
            if arr[j] < arr[min_index]:
                min_index = j
        arr[i], arr[min_index] = arr[min_index], arr[i]
    return arr

3 插入排序(Insertion Sort)

插入排序是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

时间复杂度:O(n^2)(最坏情况)

空间复杂度:O(1)

def insertion_sort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        j = i - 1
        while j >= 0 and key < arr[j]:
            arr[j + 1] = arr[j]
            j -= 1
        arr[j + 1] = key
    return arr

4 希尔排序(Shell Sort)

希尔排序是插入排序的一种更高效的改进版本,也称为缩小增量排序。它通过将待排序序列划分为若干个子序列,先对子序列进行直接插入排序,然后逐步合并子序列,最后进行一次全体记录的直接插入排序。

时间复杂度:O(n^1.3)(平均情况)

空间复杂度:O(1)

def shell_sort(arr):
    size = len(arr)
    gap = size // 2
    while gap > 0:
        for i in range(gap, size):
            temp = arr[i]
            j = i
            while j >= gap and arr[j - gap] > temp:
                arr[j] = arr[j - gap]
                j -= gap
            arr[j] = temp
        gap //= 2
    return arr

5 归并排序(Merge Sort)

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。它将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。

时间复杂度:O(nlogn)

空间复杂度:O(n)

def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    return merge(left, right)

def merge(left, right):
    merged = []
    left_index = 0
    right_index = 0
    while left_index < len(left) and right_index < len(right):
        if left[left_index] < right[right_index]:
            merged.append(left[left_index])
            left_index += 1
        else:
            merged.append(right[right_index])
            right_index += 1
    merged.extend(left[left_index:])
    merged.extend(right[right_index:])
    return merged

6 快速排序(Quick Sort)

快速排序是一种高效的排序算法,采用分治策略。它选择一个元素作为基准(pivot),将序列分为两部分,一部分小于基准,一部分大于基准,然后递归地对这两部分进行排序。

时间复杂度:O(nlogn)(平均情况)

空间复杂度:O(logn)(递归调用栈)

def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort(left) + middle + quick_sort(right)

7 堆排序(Heap Sort)

堆排序是一种基于堆数据结构的排序算法,它利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

时间复杂度:O(nlogn)

空间复杂度:O(1)

def heapify(arr, n, i):
    largest = i
    left = 2 * i + 1
    right = 2 * i + 2

    if left < n and arr[i] < arr[left]:
        largest = left

    if right < n and arr[largest] < arr[right]:
        largest = right

    if largest != i:
        arr[i], arr[largest] = arr[largest], arr[i]
        heapify(arr, n, largest)

def heap_sort(arr):
    n = len(arr)

    # Build a maxheap
    for i in range(n // 2 - 1, -1, -1):
        heapify(arr, n, i)

    # One by one extract elements
    for i in range(n - 1, 0, -1):
        arr[i], arr[0] = arr[0], arr[i]
        heapify(arr, i, 0)

    return arr

四、排序算法的比较与选择

选择排序算法时,需要考虑多个因素,包括时间复杂度、空间复杂度、稳定性、数据的特性等。

例如,对于小规模的数据,简单排序算法(如冒泡排序、选择排序、插入排序)可能更为合适,因为它们的实现简单且不需要额外的空间。然而,对于大规模的数据,更高效的排序算法(如快速排序、归并排序、堆排序)可能更为适合。

此外,对于某些特定类型的数据,如已经部分排序的数据或具p有特定分布的数据,某些排序算法可能具有更好的性能。

例如,对于几乎已经排序的数据,插入排序和冒泡排序可能具有更好的性能。对于大量重复元素的数据,计数排序和基数排序可能更为适合。

五、结论

排序算法是计算机科学中的重要组成部分,它们在各种应用中发挥着重要作用。了解各种排序算法的原理、特性和性能,对于有效地解决排序问题至关重要。在实际应用中,应根据具体的需求和数据的特性选择合适的排序算法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/432080.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

内存安全的编程语言

美国政府新颁布《回归基础构件&#xff1a;通往安全软件之路》 《回归基础构件&#xff1a;通往安全软件之路》中&#xff0c;白宫国家网络主任办公室&#xff08;ONCD&#xff09;呼吁开发者使用「内存安全的编程语言」 内存安全的编程语言 根据NSA的建议&#xff0c;内存…

Jenkins设置使用163邮箱发送邮件

目录 一、下载需要的插件 二、开通163邮箱的SMTP服务 三、配置邮箱&#xff0c;测试发送 1、配置Jenkins Location 2、配置Extended E-mail Notification 扩展邮件通知 3、配置默认触发器&#xff08;可先不配置&#xff09; ​编辑 4、配置默认的邮件通知 5、测试邮箱…

Jenkins发送邮件、定时执行、持续部署

集成Allure报告只需要配置构建后操作即可。但如果是web自动化&#xff0c;或是用HTMLTestRunner生成报告&#xff0c;构建后操作要选择Publish HTML reports&#xff0c;而构建中还要添加Execute system Groovy script插件&#xff0c;内容&#xff1a; System.setProperty(&q…

VMvare17安装centos8安装宝塔面板 教程

阿里镜像站&#xff1a;https://mirrors.aliyun.com/centos centos-8-isos-x86_64安装包下载_开源镜像站-阿里云 https://mirrors.aliyun.com/centos/8/isos/x86_64/CentOS-8.5.2111-x86_64-dvd1.iso 将上面的链接复制到迅雷进行高速下载 vmvare安装配置教程安装教程 CentOS…

MySQL学习笔记(一)数据库事务隔离级别与多版本并发控制(MVCC)

一、数据库事务隔离级别 数据库事务的隔离级别有4种&#xff0c;由低到高分别为Read uncommitted &#xff08;读未提交&#xff09;、Read committed&#xff08;读提交&#xff09; 、Repeatable read&#xff08;可重复读&#xff09; 、Serializable &#xff08;串行化&a…

爬虫学习笔记-requests爬取NBA得分榜

1.导入requests库,用于请求获取URL位置的资源 import requests 2.导入lxml库,解析及生成xml和html文件 from lxml import etree 3.定义发送请求的地址 url https://nba.hupu.com/stats/players 4.定义请求头 headers {User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64…

机器学习-面经(part6、集成学习)

10 集成学习 定义:通过结合多个学习器(例如同种算法但是参数不同,或者不同算法),一般会获得比任意单个学习器都要好的性能,尤其是在这些学习器都是"弱学习器"的时候提升效果会很明显。 10.1 Boosting(提升法) 可以用于回归和分类 问题,它每一…

Zabbix监控容器MongoDB,报错:Unknown metric mongodb.server.status

在Zabbix中配置监控MongoDB容器时&#xff0c;如果遇到Unknown metric mongodb.server.status这样的错误&#xff0c;通常意味着Zabbix Agent尝试从MongoDB获取某个预定义的性能指标&#xff08;例如mongodb.server.status&#xff09;&#xff0c;但是未能成功识别或解析该指标…

政安晨【TypeScript高级用法】(四):模块与声明文件

TypeScript是一种静态类型的JavaScript超集语言&#xff0c;它支持模块化开发和声明文件。 模块化开发是一种将代码分割为独立的模块&#xff0c;每个模块只关注自己的功能&#xff0c;然后通过导入和导出来实现模块之间的交互和复用。在TypeScript中&#xff0c;可以使用impo…

Day18:信息打点-小程序应用解包反编译动态调试抓包静态分析源码架构

目录 小程序获取-各大平台&关键字搜索 小程序体验-凡科建站&模版测试上线 小程序抓包-Proxifier&BurpSuite联动 小程序逆向-解包反编译&动态调试&架构 思维导图 章节知识点 Web&#xff1a;语言/CMS/中间件/数据库/系统/WAF等 系统&#xff1a;操作系…

第十五届蓝桥杯青少组STEMA测评SPIKE初级真题试卷 2024年1月

第十五届蓝桥杯青少组STEMA测评SPIKE初级真题试卷 2024年1月 ​​​​​​​ 来自&#xff1a;6547网 http://www.6547.cn/doc/vywur8eics

hive实战项目:旅游集市数仓建设

旅游集市数仓建设 文章目录 旅游集市数仓建设为什么要设计数据分层&#xff1f;分层设计ODS&#xff08;Operational Data Store&#xff09;&#xff1a;数据运营层DW&#xff08;Data Warehouse&#xff09;&#xff1a;数据仓库层DWD&#xff08;Data Warehouse Detail&…

Neo4j 新手教程 环境安装 基础增删改查 python链接 常用操作 纯新手向

Neo4j安装教程&#x1f680; 目前在学习知识图谱的相关内容&#xff0c;在图数据库中最有名的就是Neo4j,为了降低入门难度&#xff0c;不被网上很多华丽呼哨的Cypher命令吓退&#xff0c;故分享出该文档&#xff0c;为自己手动总结&#xff0c;包括安装环境&#xff0c;增删改查…

PRewrite: Prompt Rewriting with Reinforcement Learning

PRewrite: Prompt Rewriting with Reinforcement Learning 基本信息 2024-01谷歌团队提交到arXiv 博客贡献人 徐宁 作者 Weize Kong&#xff0c;Spurthi Amba Hombaiah&#xff0c;Mingyang Zhang 摘要 工程化的启发式编写对于LLM&#xff08;大型语言模型&#xff09;应…

LeNet5实战——衣服分类

搭建模型训练代码&#xff08;数据处理、模型训练、性能指标&#xff09;——> 产生权重w ——>模型结构c、w测试 配置环境 Pycharm刚配置的环境找不到了-CSDN博客 model.py 导入库 import torch from torch import nn from torchsummary import summary 模型搭…

三步骤找到用户真正痛点 提高需求分析质量

用户痛点对于需求分析具有至关重要的作用&#xff0c;这直接关系着需求分析结果是否真正满足用户需求&#xff0c;关系着最终研发的产品是否能够满足市场的需求&#xff0c;是否能够在竞争激烈的市场中脱颖而出。因此找到用户真正痛点至关重要。 1、什么是痛点 痛点是消费者心理…

Unity2013.1.19_DOTS_Burst compiler

Unity2013.1.19_DOTS_Burst compiler DOTS是一种新产品&#xff0c;现在尚在起步阶段。由于它处于持续发展中&#xff0c;随着我们努力使其达到最佳状态&#xff0c;您将看到API会不断演变和日趋成熟。 DOTS包含以下元素&#xff1a; 实体组件系统(ECS) - 提供使用面向数据的…

Linux下下载安装JDK配置Java环境变量

Linux下下载安装JDK配置Java环境变量 1. 下载JDK 下载链接&#xff1a;(https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) 2. 上传至服务器并解压 可通过shell工具进行上传&#xff0c;我这里是上传安装在/opt目录 解压jdk-17.0.10_linux-x64_b…

【DevOps云实践】不同Azure Function的类型

【DevOps云实践】不同Azure Function的类型 Azure函数是由Microsoft Azure提供的无服务器计算服务,允许开发人员构建和部署应用程序而不必担心底层基础设施。使用Azure函数,您可以根据不同的触发器执行代码,并支持多种类型的函数以满足不同的用例。在本博客文章中,我们将探…

html实体字符,已拿offer入职

面试知识点 主要内容包括html&#xff0c;css&#xff0c;前端基础&#xff0c;前端核心&#xff0c;前端进阶&#xff0c;移动端开发&#xff0c;计算机基础&#xff0c;算法与数据结构&#xff0c;设计模式&#xff0c;项目等等。 html 1.浏览器页面有哪三层构成&#xff0c…