八大排序算法(C语言版)之插入排序

八大排序详解

  • 目录:
  • 一、排序的概念
    • 1.1 排序的概念
    • 1.2 排序的应用
  • 二、直接插入排序
  • 三、希尔排序
  • 四、排序算法复杂度及稳定性分析

目录:

八大排序算法:

八大排序算法
插入排序
选择排序
交换排序
归并排序
非比较排序
直接插入排序
希尔排序
选择排序
堆排序
冒泡排序
快速排序
归并排序
计数排序

超链接:
插入排序
选择排序
交换排序
归并排序
非比较排序

一、排序的概念

1.1 排序的概念

排序:所谓排序,就是使一串记录, 按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j], 且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。
内部排序:数据元素全部放在内存中的排序。
外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。

1.2 排序的应用

排序的目的通常是为了方便查找,或者统计最多或者最少的重复次数。
1.游戏竞赛。 游戏规则是随机一组30张图片,要求参加比赛的10人在30秒之内把图片按照从小到大顺序排序,时间最少的获胜。
2.调查问卷。 在1~10000中随机生成N个数,对于重复的数只保留一个,不同的数对应着不同学生的学号,再把这些数从小到大排序,按顺序找同学调查。
3.颁发特等奖学金。 某个大学有n名学生,每个人都有m门课,按照综合成绩排名,需要挑出最优秀的k位学生颁发特等奖学金。

二、直接插入排序

直接插入排序的基本思想:
把待排序的内容记录并逐一与排序好的有序序列比较,插入到有序序列中,直到待排序列的记录全部插入完毕,得到一个新的有序序列,这就是直接插入排序
在这里插入图片描述
代码如下

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <time.h>
#include <windows.h>
#define m 1000
void IsertSort(int* arr, int n)
{int i;for (i = 1; i < n; i++)//i为待排序的第一个数下标{int end = i - 1;//end 为已排好序列的尾下标int tmp = arr[i];//把待排序的第一个数存起来//遍历已排序列,进行比较然后插入,这里我进行从小到大排序while (end >= 0){if (arr[end] > tmp)//如果前面的数大,就把他往后移动一个{arr[end + 1] = arr[end];end--;}//否则就跳出elsebreak;arr[end + 1] = tmp;}}//打印排序后的数据for (i = 0; i < n; i++){printf("%d ", arr[i]);}
}
int main()
{int head, end,arr[m];//srand(初始化时间),time(直接返回时间戳)srand((unsigned)time(NULL));head = clock();for (int i = 0; i < m; i++)arr[i] = rand();//,时间不停的变化,每次产生不同的随机值IsertSort(arr,sizeof(arr)/sizeof(arr[0]));end = clock();//排序需要花费的时间printf("\n%d\n ", end - head);return 0;
}

直接插入排序的性能总结:
1.元素集合越接近有序,直接插入排序算法的时间效率越高。
2.时间复杂度:O(N^2)
3.空间复杂度为:O(1),它是一种稳定的排序算法
4.稳定性:稳定

三、希尔排序

希尔排序又叫缩小增量法。
希尔排序的基本思想:
先选定一个整数,然后把待排序的记录分成这个整数的组,所有距离为这个整数的记录被分在同一个组,并对每一个组内的记录进行排序。先预排序,然后在插入排序。

在这里插入图片描述
代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <Windows.h>
#define m 10000
SheelSort(int* arr, int n)
{int gap = 3;//多趟for(int j=0;j<gap; j++)//每组进行插入排序for (int i =j; i < n - gap; i += gap){//单趟int end = i;int tmp = arr[end + gap];while (end >= 0){if (arr[end] < tmp)//从大到小排序{arr[end + gap] = arr[end];end -= gap;}elsebreak;   }arr[end + gap] = tmp;}
}
int main()
{int head, tail, i;int arr[m] = {0};srand((unsigned)time(NULL));for (i = 0; i < m; i++)arr[i] = rand()%1000;head = clock();SheelSort(arr, sizeof(arr) / sizeof(arr[0]));tail = clock();printf("%d ", tail - head);return 0;
}

效率如下
在这里插入图片描述
我们可以优化一下(减少一个循环,但是效率还是差不多得,而且代码更简洁):

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <Windows.h>
#define m 10000
SheelSort_1(int* arr, int n)
{int gap = 3;//按顺序,一组一组排序for (int i = 0; i < n - gap; i ++){//单趟int end = i;int tmp = arr[end + gap];while (end >= 0){if (arr[end] < tmp)//从大到小排序{arr[end + gap] = arr[end];end -= gap;}elsebreak;}arr[end + gap] = tmp;}
}
int main()
{int head, tail, i;int arr[m] = {0};srand((unsigned)time(NULL));for (i = 0; i < m; i++)arr[i] = rand()%1000;head = clock();SheelSort_1(arr, sizeof(arr) / sizeof(arr[0]));tail = clock();printf("%d ", tail - head);return 0;
}

在这里插入图片描述
我们可以得知预排序的意义
1.gap越大,大的数可以更快的到后面,小的数可以更快到前面,gap越大跳的越快,越不接近有序。
2.gap越小,大的小的数挪动越慢,越接近有序。
3.gap= =1,就是直接插入排序。
但是我们不知道gap取什么值最好
我们在把代码变一变,让gap无论是多少,最后都等于gap= =1.(gap >1为预排序)

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <Windows.h>
#define m 10000
SheelSort_3(int* arr, 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 = arr[end + gap];while (end >= 0){if (arr[end] < tmp)//从大到小排序{arr[end + gap] = arr[end];end -= gap;}elsebreak;}arr[end + gap] = tmp;}}
}
int main()
{int head, tail, i;int arr[m] = {0};srand((unsigned)time(NULL));for (i = 0; i < m; i++)arr[i] = rand()%1000;head = clock();SheelSort_3(arr, sizeof(arr) / sizeof(arr[0]));tail = clock();printf("%d ", tail - head);return 0;
}

计算它的时间复杂度?

1.gap很大时gap=n / 3+1,可分为n/3组数据,每组3个元素,每组最坏的比较次数为3次所以一共:n / 3 * 3次。
2.gap很小时,gap=1,每组1个元素,很接近有序,间距为gap的这些数据,数据往后挪动的次数:n。
3.gap很大时,n / 9个组,9个元素,每组最坏比较36次。(1+2……+8),间距为gap的这些数据。合计挪动数据:n / 9* 36=4n次
4.外面那个循环运算了log3^N次
总结:合计n / gap组,每组gap个,每组插入:1+2+3+……+gap。合计:(1+gap) * gap / 2
时间复杂度O(N^1.3)最好情况

稳定性:不稳定

四、排序算法复杂度及稳定性分析

如图:
在这里插入图片描述
表格:
在这里插入图片描述

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

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

相关文章

[极客大挑战 2019]Havefun

1.打开链接 2.检查一下源代码 发现一段代码。 3.分析代码 <!-- $cat$_GET[cat]; echo $cat; if($catdog){ echo Syc{cat_cat_cat_cat}; } --> 询问ChatGPT&#xff1a; 从您提供的代码片段来看&#xff0c;这是…

C++中低级内存操作

C中低级内存操作 C相较于C有一个巨大的优势&#xff0c;那就是你不需要过多地担心内存管理。如果你使用面向对象的编程方式&#xff0c;你只需要确保每个独立的类都能妥善地管理自己的内存。通过构造和析构&#xff0c;编译器会帮助你管理内存&#xff0c;告诉你什么时候需要进…

GB/T 29734.2-2013 铝塑复合门窗检测

铝合金门窗是指采用铝塑复合型材制作框、扇杆件结构的门、窗的总称&#xff0c;根据门窗开启形式的不同&#xff0c;可分为固定窗、平开窗、推拉窗&#xff0c;悬窗等。 GB/T 29734.2-2013 铝塑复合门窗检测项目 测试项目 测试标准 外观质量 GB/T 29734.2 尺寸 GB/T 2973…

面试经验——面试项目准备工作

摘要 本博文主要是分享个人在面试中对于项目思考&#xff0c;希望帮助大家能够面试中能够很好的介绍和分享自己的项目。在面试官心中留下一个好印象&#xff0c;希望你能拿到自己满意的offer。 一、面试项目常见问题 1.1 工作经历中&#xff0c;最优技术挑战/亮点的事情是什…

Elasticsearch聚合----aggregations的简单使用

文章目录 Getting started1、搜索 address 中包含 mill 的所有人的年龄分布以及平均年龄&#xff0c;但不显示这些人的详情2、size0不展示命中记录&#xff0c;只展示聚合结果3、按照年龄聚合&#xff0c;并且请求这些年龄段的这些人的平均薪资4、查出所有年龄分布&#xff0c;…

【Android Studio】工程中文件Annotate with Git Blame 不能点击

问题描述 工程文件中想要查看代码提交信息但是相关按钮不可点击 解决方法 Android Studio -> Preferences -> Version Control-> 在Unregistered roots里找到你想要的工程文件 点击左上角➕号 然后右下角Apply即可

Python分享之多进程初步 (multiprocessing包)

我们已经见过了使用subprocess包来创建子进程&#xff0c;但这个包有两个很大的局限性&#xff1a;1) 我们总是让subprocess运行外部的程序&#xff0c;而不是运行一个Python脚本内部编写的函数。2) 进程间只通过管道进行文本交流。以上限制了我们将subprocess包应用到更广泛的…

【异常】理解Java中的异常处理机制

标题&#xff1a;理解Java中的异常处理机制 摘要&#xff1a; 异常处理是Java编程中的重要概念之一&#xff0c;它可以帮助开发者识别和处理程序运行过程中的错误和异常情况。本文将深入探讨Java中的异常处理机制&#xff0c;包括异常的分类、异常处理的语法和最佳实践。通过示…

Filter过滤器和Listener监听器

2023.10.26 Filter过滤器 过滤器&#xff0c;顾名思义就是对事物进行过滤的。Web中的过滤器&#xff0c;就是对请求进行过滤&#xff0c;我们使用过滤器&#xff0c;就可以对请求进行拦截&#xff0c;然后做相应的处理&#xff0c;实现许多特殊功能。如登录控制&#xff0c;权…

uniapp开发小程序—picker结合后台数据实现二级联动的选择

一、效果图 二、完整代码 <template><view><picker mode"multiSelector" change"bindMultiPickerChange" columnchange"bindMultiPickerColumnChange":value"multiIndex" :range"multiArray"><view c…

基于FPGA的电风扇控制器verilog,视频/代码

名称&#xff1a;基于FPGA的电风扇控制器verilog 软件&#xff1a;QuartusII 语言&#xff1a;Verilog 代码功能&#xff1a; 基于FPGA的电风扇控制器 运用 EDA SOPO实验开发系统设计一个基于FPGA的电风扇定时开关控制器,能实现手动和自动模式之间的切换。要求: (1)KI为电…

【Gensim概念】03/3 NLP玩转 word2vec

第三部分 对象函数 八 word2vec对象函数 该对象本质上包含单词和嵌入之间的映射。训练后&#xff0c;可以直接使用它以各种方式查询这些嵌入。有关示例&#xff0c;请参阅模块级别文档字符串。 类型 KeyedVectors 1&#xff09; add_lifecycle_event(event_name, log_level2…

@AutoConfigurationPackage注解类

包名package org.springframework.boot.autoconfigure 方法 String[] basePackages() 向AutoConfigurationPackages中注册的基本包&#xff0c;使用basePackageClasses作为基于字符串的包的类型安全替代方案 Class<?>[] basePackageClasses() 键入basePackage…

APP破解去广告

1.修改图标和名称 名称直接改 找到图标在进去把他替换掉 2.修改app包名实现分身 修改包名实现app分身_Tian翊的博客-CSDN博客 3.修改资源去广告 安卓逆向006之修改APK资源去广告_修改安装包去除app内广告-CSDN博客 打开模拟器后在cmd命令行输入adb devices连接上 在模拟器中…

【多线程】探索Java中的多线程编程

标题&#xff1a;探索Java中的多线程编程 摘要&#xff1a; Java是一种广泛使用的编程语言&#xff0c;具有强大的多线程编程能力。本文将深入探讨Java中的多线程编程&#xff0c;包括线程的创建、同步与互斥、线程池的使用以及常见的多线程编程模式。通过示例代码和详细解释&…

每日一练——返回链表的中间结点

&#x1d649;&#x1d65e;&#x1d658;&#x1d65a;!!&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦ &#x1f44f;&#x1f3fb;‧✧̣̥̇:Solitary-walk ⸝⋆ ━━━┓ - 个性标签 - &#xff1a;来于“云”的“羽球人”。…

【单元测试】--维护和改进单元测试

一、持续维护单元测试 持续维护单元测试是确保它们继续有效的关键。以下是一些方法来保持单元测试的可维护性&#xff1a; 集成单元测试到持续集成流程&#xff1a;将单元测试包括在持续集成&#xff08;CI&#xff09;流程中&#xff0c;确保它们在每次代码更改后都自动运行…

Dockerfile文件自动化生成R4L镜像

Dockerfile文件自动化生成R4L镜像的步骤 1、安装Docker&#xff1a;2、使用Dockerfile一键生成镜像&#xff1a;3、查看生成的Docker镜像&#xff1a;4、删除Docker镜像&#xff1a;5、生成Docker容器&#xff1a;6、查看容器7、删除容器 1、安装Docker&#xff1a; curl -fsS…

sqoop和flume简单安装配置使用

1. Sqoop 1.1 Sqoop介绍 Sqoop 是一个在结构化数据和 Hadoop 之间进行批量数据迁移的工具 结构化数据可以是MySQL、Oracle等关系型数据库 把关系型数据库的数据导入到 Hadoop 与其相关的系统 把数据从 Hadoop 系统里抽取并导出到关系型数据库里 底层用 MapReduce 实现数据 …

如何巧妙告知家长成绩分数

如何让学生和家长们查询期中考试成绩,一直是让许多老师都头疼不已的问题。今天我就来交给大家怎么解决这个问题。 我们先了解一下成绩查询系统是什么。在互联网高度发达的今天&#xff0c;成绩查询系统已经不再是学校的专属&#xff0c;而是可以通过网络平台进行操作的一种工具…