数据结构与算法之排序

9.1 排序的概念

1. 排序的定义
  • 定义:排序是将表中的记录按关键字递增(或递减)有序排列的过程。
  • 说明:数据中可以存在相同关键字的记录。本章主要考虑递增排序。
  • 扩展:排序是数据处理中的基本操作之一,广泛应用于数据库管理、信息检索等领域。排序可以提高数据的可读性和可操作性,便于后续的查找、统计等操作。
2. 内排序和外排序
  • 内排序:整个表都在内存中处理,不涉及数据的内外存交换。
  • 外排序:排序过程中需要进行数据的内外存交换。
  • 扩展:内排序适用于数据量较小的情况,因为内存访问速度快,效率较高。外排序适用于数据量较大的情况,通常需要将数据分块处理,然后合并排序结果。
3. 内排序的分类
  • 插入排序:通过将元素插入到已排序部分的适当位置来实现排序。
  • 交换排序:通过交换元素的位置来实现排序,如冒泡排序。
  • 选择排序:通过选择未排序部分的最小(或最大)元素与当前元素交换来实现排序。
  • 归并排序:将数据分成多个小部分进行排序,然后将排序好的部分合并。
  • 基于比较的排序算法:如插入排序、交换排序、选择排序、归并排序等。
  • 不基于比较的排序算法:如基数排序。
  • 扩展:不同的排序算法适用于不同的场景,选择合适的排序算法可以提高程序的效率。例如,插入排序适用于部分有序的数据,而归并排序适用于大规模数据的排序.
4.小结
  • 排序的概念定义递增或递减排列
      • 允许相同关键字
    • 内排序 vs 外排序内排序:内存中处理
      • 外排序:内外存交换
    • 内排序分类插入排序
      • 交换排序
      • 选择排序
      • 归并排序
      • 基数排序

9.2插入排序

9.2.1 直接插入排序
基本思路
  • 有序区和无序区:初始时,有序区只有一个元素(通常是第一个元素),无序区包含其余所有元素。
  • 排序过程:每次从未排序区取出一个元素,插入到有序区的适当位置,使得有序区仍然保持有序。
  • 步骤将待插入元素与有序区的元素从后向前比较。
    • 如果待插入元素小于当前比较的元素,则将当前元素后移一位。
    • 重复上述步骤,直到找到待插入元素的正确位置。
    • 将待插入元素插入到该位置。
Python实现

def insert_sort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        j = i - 1
        # 将arr[i]插入到已排序序列arr[0...i-1]中
        while j >= 0 and key < arr[j]:
            arr[j + 1] = arr[j]
            j -= 1
        arr[j + 1] = key
    return arr

# 示例
arr = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
print("原始数组:", arr)
insert_sort(arr)
print("排序后的数组:", arr)

算法分析
  • 时间复杂度最好情况:输入序列已经是正序的,时间复杂度为 O(n)。
    • 最坏情况:输入序列是反序的,时间复杂度为 O(n2)。
    • 平均情况:时间复杂度为 O(n2)。
  • 空间复杂度O(1),因为只需要一个额外的变量来存储待插入的元素。
  • 稳定性:稳定排序算法,因为相同元素的相对顺序不会改变。

eg设待排序的表有10个元素,其关键字分别为(9,8,7,6,5,4,3,2,1,0)

9.2.2 折半插入排序

基本思路
  • 折半查找:在有序区中使用折半查找方法来确定待插入元素的位置,从而减少比较次数。
  • 步骤将待插入元素保存在一个临时变量中。
    • 使用折半查找在有序区中找到待插入元素的正确位置。
    • 将有序区中从插入位置开始的所有元素后移一位,为待插入元素腾出空间。
    • 将待插入元素插入到找到的位置。
Python实现

def binary_search(arr, key, low, high):
    while low <= high:
        mid = (low + high) // 2
        if arr[mid] < key:
            low = mid + 1
        else:
            high = mid - 1
    return low

def binary_insert_sort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        # 使用折半查找找到插入位置
        pos = binary_search(arr, key, 0, i - 1)
        # 将元素后移
        for j in range(i, pos, -1):
            arr[j] = arr[j - 1]
        # 插入元素
        arr[pos] = key
    return arr

# 示例
arr = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
print("原始数组:", arr)
binary_insert_sort(arr)
print("排序后的数组:", arr)

算法分析
  • 时间复杂度比较次数:由于使用了折半查找,比较次数为 O(logn)。
    • 移动次数:移动次数仍为 O(n),因为需要将元素后移。
    • 总时间复杂度O(n2),虽然比较次数减少,但移动次数仍然较高。
  • 空间复杂度O(1),只需要一个额外的变量来存储待插入的元素。
  • 稳定性:稳定排序算法,因为相同元素的相对顺序不会改变.

9.2.3 希尔排序

基本思路
  • 分组插入:希尔排序是一种基于插入排序的改进算法,通过将待排序序列分成若干个子序列,对每个子序列进行直接插入排序。
  • 增量序列:选择一个增量序列 d1,d2,,dkd1 ,d2 ,,dk ,其中 d1>d2>>dk=1d1 >d2 >>dk =1。增量 dd 通常从 n/2n/2 开始,每次减半,直到增量为1。
  • 步骤选择一个增量 dd,将待排序序列分成 dd 个子序列。
    • 对每个子序列进行直接插入排序。
    • 减小增量 dd,重复上述步骤,直到增量为1。
Python实现

def shell_sort(arr):
    n = len(arr)
    gap = n // 2  # 初始增量
    while gap > 0:
        for i in range(gap, n):
            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

# 示例
arr = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
print("原始数组:", arr)
shell_sort(arr)
print("排序后的数组:", arr)

算法分析
  • 时间复杂度最好情况O(nlogn)O(nlogn),当增量序列选择得当且数据接近有序时。
    • 最坏情况O(n2)O(n2),但通常比直接插入排序要好。
    • 平均情况:通常为 O(n1.3)O(n1.3) O(n1.5)O(n1.5),具体取决于增量序列的选择。
  • 空间复杂度O(1)O(1),因为只需要一个额外的变量来存储待插入的元素。
  • 稳定性:不稳定排序算法,因为相同元素的相对顺序可能会改变.

希尔排序过程解释

  1. 初始序列9, 8, 7, 6, 5, 4, 3, 2, 1, 0
  2. 第一次排序(d=5)
    1. 增量 d 被设置为数组长度的一半,即 5
    2. 将数组分为 5 组,每组包含相隔 5 个位置的元素:{9, 4}, {8, 3}, {7, 2}, {6, 1}, {5, 0}
    3. 对每组进行直接插入排序。例如,第一组 9, 4 排序后变为 4, 9
    4. 数组变为4938271605
  3. 第二次排序(d=2)
    1. 增量 d 减半,变为 2
    2. 将数组分为 2 组,每组包含相隔 2 个位置的元素:{4, 3, 2, 1}, {9, 8, 7, 6}, {5, 0}
    3. 对每组进行直接插入排序。例如,第一组 4, 3, 2, 1 排序后变为 1, 2, 3, 4
    4. 数组变为1234678905
  4. 第三次排序(d=1)
    1. 增量 d 再次减半,变为 1因为整一个数组基本有序,最后进行一次直接插入排序时间复杂度就约等于O(n),在这里除了0和5其它元素都是直接放入有序区。
    2. 此时,整个数组作为一个组进行直接插入排序。
    3. 由于前两次排序已经将数组中的元素大致排列好了,这次排序将它们排列成完全有序的序列:0, 1, 2, 3, 4, 5, 6, 7, 8, 9

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

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

相关文章

Swagger学习⑩——@Server注解

介绍 Server 是 Swagger/OpenAPI 3.0 注解中的一个注解&#xff0c;用于定义 API 文档中的服务器信息。通过 Server 注解&#xff0c;你可以指定 API 服务的基础 URL 或其他相关信息。 源代码 package io.swagger.v3.oas.annotations.servers;import io.swagger.v3.oas.anno…

MATLAB仿真:基于GS算法的经大气湍流畸变涡旋光束波前校正仿真

GS算法流程 GS&#xff08;Gerchberg-Saxton&#xff09;相位恢复算法是一种基于傅里叶变换的最速下降算法&#xff0c;可以通过输出平面和输入平面上光束的光强分布计算出光束的相位分布。图1是基于GS算法的涡旋光束畸变波前校正系统框图&#xff0c;在该框图中&#xff0c;已…

C语言笔记之`char*`、`const char*` 和 `char[]`辨析

C语言笔记之char*、const char* 和 char[]辨析 code review! 参考笔记 1.C语言笔记之char*、const char* 和 char[]辨析 2.C++笔记之int、size_t、uint8_t、unsigned char*区别 3.C++之char和string字符串类探究 4.C++笔记之字节数组的处理 5.C++笔记之如何给 const char* 类型…

十种基础排序算法(C语言实现,带源码)(有具体排序例子,适合学习理解)

学习了十种常见的排序方法&#xff0c;此文章针对所学的排序方法进行整理&#xff08;通过C语言完成排序&#xff09;。 参考内容&#xff1a; https://blog.csdn.net/mwj327720862/article/details/80498455 https://www.runoob.com/w3cnote/ten-sorting-algorithm.html 1. 冒…

Timer、Ticker使用及其注意事项

Timer、Ticker使用及其注意事项 在刚开始学习golang语言的时候就听说Timer、Ticker的使用要尤其注意&#xff0c;很容易出现问题&#xff0c;这次就来一探究竟。 本文主要脉络&#xff1a; 介绍定时器体系&#xff0c;并介绍常用使用方式和错误使用方式源码解读 timer、tic…

密码学科普

1 信息传输中的安全隐患 1. 窃听 解决方案&#xff1a;明文加密&#xff0c;X只能窃听到密文 2. 假冒 解决方案&#xff1a;消息认证码或者数字签名 3. 篡改 解决方案&#xff1a;消息认证码或者数字签名 4. 事后否认 解决方案&#xff1a;数字签名 2 对称加密/非对称加密 1…

MMPose关键点检测实践(一)

一&#xff0c;安装环境 这一步&#xff0c;需根据自己的硬件环境&#xff0c;按照以下文档安装即可&#xff0c;最大的变数就是不同的硬件&#xff0c;对应的软件版本不一样&#xff0c;这个因人而异&#xff0c;没有统一版本。mmpose安装说明&#xff1a; https://mmpose.r…

指针 const 的组合

1、首先来了解一下常量 const int num 5&#xff1b; 那么num的值是5&#xff0c; num的值不可修改 2、来了解一下指针 int value 5; int* p &value; 我喜欢吧指针和类型放一起&#xff0c;来强调p是一个指针类型&#xff0c; 而赋值的时候就得赋值一个int类型的地址…

Unity-Mirror网络框架从入门到精通之Attributes属性介绍

前言 在现代游戏开发中&#xff0c;网络功能日益成为提升游戏体验的关键组成部分。Mirror是一个用于Unity的开源网络框架&#xff0c;专为多人游戏开发设计。它使得开发者能够轻松实现网络连接、数据同步和游戏状态管理。本文将深入介绍Mirror的基本概念、如何与其他网络框架进…

【大数据】(选修)实验4 安装熟悉HBase数据库并实践

实验4 安装熟悉HBase数据库并实践 1、实验目的 (1)理解HBase在Hadoop体系结构中的角色; (2)熟练使用HBase操作常用的Shell命令; (3)熟悉HBase操作常用的Java API。 2、实验平台 操作系统:Linux Hadoop版本:2.6.0或以上版本 HBase版本:1.1.2或以上版本 JDK版…

VVenC 编码器源码结构与接口函数介绍

VVenC VVenC&#xff08;Fraunhofer Versatile Video Encoder&#xff09;是由德国弗劳恩霍夫海因里希研究所&#xff08;Fraunhofer Heinrich Hertz Institute, HHI&#xff09;开发的一个开源的高效视频编码器。它实现了最新的视频编码标准——Versatile Video Coding (VVC)…

Nginx与frp结合实现局域网和公网的双重https服务

背景&#xff1a; 因为局域网内架设了 tiddlywiki、 Nextcloud 等服务&#xff0c;同时也把公司的网站架设在了本地&#xff0c;为了实现局域网直接在局域网内访问&#xff0c;而外部访问通过frps服务器作为反向代理的目的&#xff0c;才有此内容。 实现的效果如下图琐事 不喜欢…

PDFelement 特别版

Wondershare PDFelement Pro 是一款非常强大的PDF编辑软件&#xff0c;它允许用户轻松地编辑、转换、创建和管理PDF文件。这个中文特别版的软件具有许多令人印象深刻的功能&#xff0c;PDFelement Pro 提供了丰富的编辑功能&#xff0c;可以帮助用户直接在PDF文件中添加、删除、…

SPSS实现中介效应与调节效应

1. 中介效应 SPSS 实现 本例研究的自变量&#xff08;X&#xff09; “工作不被认同”&#xff1b;中介变量&#xff08;M&#xff09;为“焦虑”&#xff0c;因变量&#xff08;Y&#xff09;为“工作绩效”。探讨焦虑是否在工作不被认同与工作绩效间的作用。 &#xff08;2&…

Spring 复习笔记

文章目录 Spring IoC / DISpring IoC / DI 核心概念Spring 组件管理概念Spring IoC / DI 概念Spring Ioc 容器具体接口和实现类Spring Ioc 的管理方式 基于 XML 方式管理 BeanSpring IoC/ / DI 实现步骤第一步&#xff1a;导入依赖配置元数据第二步&#xff1a;实例化 IoC 容器…

免费GEMINI模型使用及API调用

一、概述 谷歌最新发布的Gemini 2.0 FLASH模型为AI应用带来了新的可能性。该模型分为两个版本&#xff1a;gemini-2.0-flash-exp 和 gemini-2.0-flash-thinking-exp-1219。这两个模型目前限时免费使用&#xff0c;用户可以通过智匠MindCraft客户端或小程序直接体验&#xff0c;…

探索 ES6 Set:用法与实战

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

《探秘计算机视觉与深度学习:开启智能视觉新时代》

《探秘计算机视觉与深度学习&#xff1a;开启智能视觉新时代》 一、追溯起源&#xff1a;从萌芽到崭露头角二、核心技术&#xff1a;解锁智能视觉的密码&#xff08;一&#xff09;卷积神经网络&#xff08;CNN&#xff09;&#xff1a;图像识别的利器&#xff08;二&#xff0…

HTML+CSS+JS制作高仿小米官网网站(内附源码,含6个页面)

一、作品介绍 HTMLCSSJS制作一个高仿小米官网网站&#xff0c;包含首页、商品详情页、确认订单页、订单支付页、收货地址管理页、新增收获地址页等6个静态页面。其中每个页面都包含一个导航栏、一个主要区域和一个底部区域。 二、页面结构 1. 顶部导航栏 包含Logo、主导航菜…

ssl证书免费申请指南!一行命令,一分钟搞定SSL证书自动续期。

一行命令&#xff0c;一分钟轻松搞定SSL证书自动续期。 快速开始 ​一行命令&#xff0c;一分钟轻松搞定SSL证书自动续期。 适合nginx配置过SSL证书的用户&#xff0c;如果是第一次配置SSL证书&#xff0c;请参考手把手教程 一、安装httpsok 登陆PC控制台 &#x1f449; &…