【数据结构】排序(直接插入排序,希尔排序)

目录

一、排序的概念

 二、常见的排序算法

 三、插入排序

1.直接插入排序

 1.直接插入排序实现

2.直接插入排序特性及复杂度

2.希尔排序 

1.排序思路

2.希尔排序实现 

3.希尔排序的特性及复杂度 


一、排序的概念

排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次 序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排 序算法是稳定的;否则称为不稳定的。

内部排序:数据元素全部放在内存中的排序。

外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。

 二、常见的排序算法

最常用的排序算法可以分为四大类:
插入排序、选择排序、交换排序与归并排序。插入排序的代表算法有直接插入排序与希尔排序;选择排序的排序算法代表是选择排序与堆排序;交换排序中我们要熟识冒泡排序与快速排序;归并排序则主要是以归并排序算法为主,及一些由归并思想衍生出的排序算法。 

 三、插入排序

1.直接插入排序

直接插入排序是一种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为 止,得到一个新的有序序列 。

实际中我们玩扑克牌时,就用了插入排序的思想

 当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与 array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移

 1.直接插入排序实现

首先我们解决单次排序,从后向前比较,如果a[end] > tmp,则把a[end + 1] 和 a[end] 进行交换,然后再向前比较,当end跑到头时end+1刚好为0。

因为第一个数字不用排,所以需要循环n-1趟

void InserSort(int* a, int n)
{for (int i = 1; i < n; i++){int end = i - 1;int tmp = a[i];while (end >= 0){if (a[end] > tmp){a[end + 1] = a[end];end--;}else{break;}}a[end + 1] = tmp;}
}
2.直接插入排序特性及复杂度

直接插入排序的特性总结:

1. 元素集合越接近有序,直接插入排序算法的时间效率越高

2. 时间复杂度:O(N^2)

3. 空间复杂度:O(1),它是一种稳定的排序算法

4. 稳定性:稳定

2.希尔排序 

1.排序思路

        希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个 组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。

简单来说,意思是取一个整数,作为 间距gap ,对于每个元素,与其间隔为gap 的元素分成一个组,对每组排序 。不断调整gap,对每组进行不断排序,在 gap调整到 1 后进行插入排序,就可以将数据排成有序。而按照间距gap分组并排序被称为 预排序 。

所以,希尔排序可分为两步,预排序(让数据接近有序)和直接插入排序

2.希尔排序实现 

希尔排序和直接插入排序思路是差不多的,当gap = 1时二者相等

所以单次希尔排序为

for (int j = 0; j < gap; j++)
{for (int i = j; i < n - gap; i += gap){int end = i;int tmp = a[end + gap];while (end >= 0){if (a[end] > tmp){a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = tmp;}
}

这里的gap不仅是每组中元素的间距,也是组数。上面代码只完成了单组,对于完整的一组需要在外面套上一层循环,需要循环gap次

//优化
for (int i = 0; i < n - gap; i++)
{int end = i;int tmp = a[end + gap];while (end >= 0){if (a[end] > tmp){a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = tmp;
}

希尔排序的特性总结:

1. 希尔排序是对直接插入排序的优化。

2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就 会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。

3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些书中给出的希尔排序的时间复杂度都不固定 

这里为什么gap/3后要+1呢,因为每次+1,到最后必定是1 

void ShellSort(int* a, int n)
{int gap = n;while (gap > 1){gap = gap / 3 + 1;//gap = gap / 2;for (int i = 0; i < n - gap; i++){int end = i;int tmp = a[end + gap];while (end >= 0){if (a[end] > tmp){a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = tmp;}}
}
3.希尔排序的特性及复杂度 

Knuth进行了大量的试验统计,得出最接近的结论,希尔排序的最终时间复杂度为 O(N^1.3)左右。 

而空间复杂度就很简单了,并没有开辟额外的空间,所以空间复杂度为 O(1) 。

希尔排序是对直接插入排序的优化。
当 增量 > 1时都是预排序,目的是让数组更接近于有序。当增量为 1 时,数组已经接近有序了,再进行排序就能提高算法执行的时间效率。
时间复杂度:O(N^1.3) 。
空间复杂度:O(1) 。
稳定性:不稳定。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python手写数字识别(PaddlePaddle框架、MNIST数据集)

python手写数字识别&#xff08;PaddlePaddle框架、MNIST数据集&#xff09; import paddle import paddle.nn.functional as F from paddle.vision.transforms import Compose, Normalizetransform Compose([Normalize(mean[127.5],std[127.5],data_formatCHW)]) # 使用tran…

[Java基础揉碎]多线程基础

多线程基础 什么是程序, 进程 什么是线程 什么是单线程,多线程 并发, 并行的概念 单核cpu来回切换, 造成貌似同时执行多个任务, 就是并发; 在我们的电脑中可能同时存在并发和并行; 怎么查看自己电脑的cpu有几核 1.资源监视器查看 2.此电脑图标右键管理- 设备管理器- 处理器…

k8s 二进制安装 详细安装步骤

目录 一 实验环境 二 操作系统初始化配置&#xff08;所有机器&#xff09; 1&#xff0c;关闭防火墙 2&#xff0c;关闭selinux 3&#xff0c;关闭swap 4, 根据规划设置主机名 5, 做域名映射 6&#xff0c;调整内核参数 7&#xff0c; 时间同步 三 部署 dock…

原生IP介绍

原生IP&#xff0c;顾名思义&#xff0c;即初始真实IP地址&#xff0c;是指从互联网服务提供商获得的IP地址&#xff0c;IP地址在互联网与用户之间直接建立联系&#xff0c;不需要经过代理服务器代理转发。 原生IP具备以下特点。 1.直接性 原生IP可以直接连接互联网&#xff…

代码随想录算法训练营第五十四天

第二题我看了很久还是没太明白&#xff0c;我发现理解动规有一点点吃力了啊&#xff0c;努努力。 392.判断子序列 总感觉在不等于的时候&#xff0c;应该是dp[i][j] dp[i-1][j-2]; 这里其实按他那个图会更好理解一点。 class Solution { public:bool isSubsequence(string s, …

CentOs安装

安装 开发工具 &#xff1a;GCC、 JDK、mysql 如果出现蓝屏&#xff0c;要在BIOS开启虚拟化支持&#xff0c;或者移除打印机。

Google:站长移除无效网址

当您的网址不需要呈现在Google站长中时&#xff0c;您可以在站长工具中移除网址 操作步骤&#xff1a;登录Google站长&#xff0c;绑定网站完成后&#xff0c;点击左侧删除 >> 输入网址 如果遇到一些网址&#xff0c;可以找寻网址间的规律&#xff0c;比如说&#xff0…

2024生日快乐祝福HTML源码

源码介绍 2024生日快乐祝福HTML源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c; 源码截图 源码下载 2024生日快乐祝福HTML源码

Shell脚本 <<EOF ... EOF语法(Here Document)(特殊的输入重定向方式)(定界符)

文章目录 Here Document语法Here Document 的基本语法使用场景 关于定界符定界符不是变量定界符在 Here Document 中只是一个字符串&#xff0c;主要功能是标记输入文本的开始和结束&#xff0c;使用时应遵循最佳实践格式要求例子和说明如何使用定界符定界符可重复使用&#xf…

Spring数据访问全攻略:从JdbcTemplate到声明式事务

上文讲到 —— 航向数据之海&#xff1a;Spring的JPA与Hibernate秘籍 本文目录 四. JdbcTemplate的使用定义JdbcTemplate及其在Spring中的作用展示如何使用JdbcTemplate简化数据库操作1. 配置JdbcTemplate2. 使用JdbcTemplate查询数据3. 打印查询结果 五. Spring的事务管理介绍…

Linux shell编程学习笔记49:strings命令

0 前言 在使用Linux的过程中&#xff0c;有时我们需要在obj文件或二进制文件中查找可打印的字符串&#xff0c;那么可以strings命令。 1. strings命令 的功能、格式和选项说明 我们可以使用命令 strings --help 来查看strings命令的帮助信息。 pupleEndurer bash ~ $ strin…

在k8s中搭建elasticsearch高可用集群,并对数据进行持久化存储

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《洞察之眼&#xff1a;ELK监控与可视化》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Elasticsearch简介 2、k8s简介 二、环境准备 …

Git项目管理——提交项目和版本回退(二)

个人名片&#xff1a; &#x1f393;作者简介&#xff1a;嵌入式领域优质创作者&#x1f310;个人主页&#xff1a;妄北y &#x1f4de;个人QQ&#xff1a;2061314755 &#x1f48c;个人邮箱&#xff1a;[mailto:2061314755qq.com] &#x1f4f1;个人微信&#xff1a;Vir2025WB…

android绘制多个黑竖线条

本文实例为大家分享了android绘制多个黑竖线条展示的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下 1.写一个LinearLayout的布局&#xff0c;将宽度写成5dp将高度写成match_parent. 2.在写一个类继承LinearLayout&#xff0c;用LayoutInflater实现子布局的在这个L…

train_gpt2_fp32.cu - main

llm.c/test_gpt2_fp32.cu at master karpathy/llm.c (github.com) 源码 // ---------------------------------------------------------------------------- // main training loop int main(int argc, char *argv[]) {// read in the (optional) command line argumentsco…

三.使用HashiCorp Vault工具管理数据库

三.ubuntu安装使用HashiCorp Vault工具管理数据库 HashiCorp Vault 是一个基于身份的秘密和加密管理系统。机密是您想要严格控制访问的任何内容,例如 API 加密密钥、密码和证书。Vault 提供由身份验证和授权方法门控的加密服务。使用 Vault 的 UI、CLI 或 HTTP API,可以安全…

深度优先搜索汇总

常用英文 最近公共祖先&#xff08;Lowest Common Ancestor&#xff0c;简称LCA&#xff09; posterity&#xff0c;英语单词&#xff0c;主要用作名词&#xff0c;作名词时译为“子孙&#xff0c;后裔&#xff1b;后代”。 什么是深度优先搜索 深度优先搜索&#xff0c;D…

文心一言指令

文心一言 文心一言&#xff08;ERNIE Bot&#xff09;是百度公司研发的知识增强大语言模型&#xff0c;它可以根据用户的指令和输入&#xff0c;生成相应的回答或文本。以下是一些可能的指令示例&#xff0c;用于指导文心一言完成不同的任务&#xff1a; 知识问答&#xff1a…

【oracle】图片转为字节、base64编码等形式批量插入oracle数据库并查询

1.熟悉、梳理、总结下Oracle相关知识体系 2.欢迎批评指正&#xff0c;跪谢一键三连&#xff01; 资源下载&#xff1a; oci.dll、oraocci11.dll、oraociei11.dll3个资源文件资源下载&#xff1a; Instant Client Setup.exe资源下载&#xff1a; oci.dll、oraocci11.dll、oraoc…

初识C语言——第二十一天

猜数字小游戏的实现&#xff1a; 学会了之后可以自己制作彩票抽奖&#xff0c;哈哈&#xff01; 代码实现&#xff1a; #include <stdlib.h> #include <time.h>void menu()//无返回值函数 {printf("**************************\n");printf("****…