数据结构-C语言-排序(1)

        代码位置:test-c-2024: 对C语言习题代码的练习 (gitee.com)

一、前言:

1.1-排序定义:

        排序就是将一组杂乱无章的数据按照一定的规律(升序或降序)组织起来。

1.2-排序分类:

常见的排序算法:
  • 插入排序
    a. 直接插入排序
    b. 希尔排序
  • 选择排序
    a. 选择排序
    b. 堆排序
  • 交换排序
    a. 冒泡排序
    b. 快速排序
  • 归并排序
    a. 归并排序
  • 非比较排序
    a.计数排序
    b.基数排序

1.3-算法比较:

        今天,我们这里要实现的是直接插入排序希尔排序

二、直接插入排序:

2.1-思路: 

      其中传入的数组a为需要排序的数组,len为数组长度。这里的思路是直接从数组的第二个位置开始一直到数组的最后一个位置,依次与前面数据比较(当数组个数为一个时不需要排序所以从第二个数据开始比较插入),因为排序默认情况下采用升序,所以这里我们也采用升序的方式。

        原理:将tem设为要插入的元素,依次与前面元素比较,若前面元素比它大则需将tem前移直到遇到比它小的元素时才结束,并将tem插入那个元素后。

2.2-过程图:

2.3-代码如下:

        代码中我加入了打印函数便于观察插入的过程。

//升序
void InsertSort(int* a,int len)			//直接插入排序
{
	printf("原数组顺序:");
	for (int i = 0; i < len; i++)
	{
		printf("%d  ", a[i]);
	}
	printf("\n");
	for (int i = 1; i < len; i++)
	{
		int end = i - 1;
		int tem = a[i];		//插入排序从第二个元素开始
		//将tem插入到区间 [ 0 , end ] 中,保持有序
		while (end >= 0)
		{
			if (a[end] > tem)
			{
				a[end + 1] = a[end];
				end--;
			}
			else
			{
				break;
			}
		}
		a[end + 1] = tem;
		printf("排序第%d趟:", i);
		for (int i = 0; i < len; i++)
		{
			printf("%d  ", a[i]);
		}
		printf("\n");
	}
}

2.4-效果图:

2.5-性质:

由上述代码及图片见:

时间复杂度:

        直接插入排序的时间复杂度在最好的情况(原数组升序)为O(N),在最坏的情况(原数组降序)下为O(N^2).

空间复杂度:

        因为没开辟空间,所以空间复杂度为O(1)

稳定性:

        如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。 所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的

三、希尔排序:

2.1-思路:

         其中传入的数组a为需要排序的数组,len为数组长度。这里的思路是直接从数组的第gap个位置开始一直到数组的最后一个位置,依次与前面相差gap个数据位置的数据比较,因为排序默认情况下采用升序,所以这里我们也采用升序的方式。将tem设为要插入的元素,依次与前面相距gap个元素的位置比较,若前面元素比它大则需将tem前移直到遇到比它小的元素时才结束,并将tem插入那个元素后。说白了就是把相距gap个数据位置的数据放在一起比较进行插入排序。

        原理:希尔排序是按照不同步长gap对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小, 插入排序对于有序的序列效率很高。

        

 

2.3-代码如下:

 

//升序
void ShellSort(int* a, int len)				//希尔排序
{
	printf("原数组顺序:");
	for (int i = 0; i < len; i++)
	{
		printf("%d  ", a[i]);
	}
	printf("\n");
	//gap是多少合适?
	//gap越大,跳的越快,越不接近有序
	//gap越小,跳的越慢,越接近有序
	int gap = len;
	while (gap > 1)
	{
		gap = gap / 2;
		for (int j = 0; j < gap; j++)
		{
			for (int i = gap + j; i < len; i += gap)
			{
				int end = i - gap;
				int tem = a[end + gap];
				//将tem插入到区间 [ 0 , end ] 中,保持有序
				while (end >= 0)
				{
					if (a[end] > tem)
					{
						a[end + gap] = a[end];
						end -= gap;
					}
					else
					{
						break;
					}
				}
				a[end + gap] = tem;
			}
			
		}

		printf("gap=%d时排序:",gap);
		for (int i = 0; i < len; i++)
		{
			printf("%d  ", a[i]);
		}
		printf("\n");
	}
	
}

2.4-效果图:

 

2.5-性质:

由上述代码及图片见: 

时间复杂度:

  希尔排序是按照不同步长gap对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小, 插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比O(n^2)好一些。希尔排序的时间复杂度在最好的情况(原数组升序)为O(N),在最坏的情况下为O(N^1.3).

空间复杂度:

  因为没开辟空间,所以空间复杂度为O(1)

稳定性:  

        由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以希尔排序是不稳定的

        不稳定情况如图所示:

四、结语:

        上述内容,即是我个人对数据结构排序中直接插入排序希尔排序的个人见解以及自我实现。若有大佬发现哪里有问题可以私信或评论指教一下我这个小萌新。非常感谢各位友友们的点赞,关注,收藏与支持,我会更加努力的学习编程语言,还望各位多多关照,让我们一起进步吧!

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

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

相关文章

力扣第406场周赛

力扣第406场周赛 100352. 交换后字典序最小的字符串 - 力扣&#xff08;LeetCode&#xff09; 贪心&#xff0c;从 0 0 0开始扫描到 n n n如果有一个可以交换的就立马交换 class Solution { public:string getSmallestString(string s) {for(int i1;i<s.size();i){if(s[i…

结合实体类型信息(2)——基于本体的知识图谱补全深度学习方法

1 引言 1.1 问题 目前KGC和KGE提案的两个主要缺点是:(1)它们没有利用本体信息;(二)对训练时未见的事实和新鲜事物不能预测的。 1.2 解决方案 一种新的知识图嵌入初始化方法。 1.3 结合的信息 知识库中的实体向量表示&#xff0b;编码后的本体信息——>增强 KGC 2基…

PHP webshell 免杀方法

本文介绍php类webshell简单的免杀方法&#xff0c;总结不一定全面&#xff0c;仅供读者参考。 webshell通常可分为一句话木马&#xff0c;小马&#xff0c;大马&#xff0c;内存马。 一句话木马是最简单也是最常见的webshell形式&#xff0c;这种木马体积小&#xff0c;隐蔽较…

图解超详细!!!!!!算法刷题之路之链表初探(五)反转链表

算法刷题之路之链表初探&#xff08;五&#xff09; 今天来学习的算法题是leecode206反转链表&#xff0c;是一道简单的入门题&#xff0c;话不多说&#xff01;直接上&#xff01; 条件 图解&#xff08;先看图结合后面的思路一起看&#xff09; 项目解释 有题目可以知道&…

记录些MySQL题集(3)

MySQL 分区技术深入解析 分区的基本概念 MySQL分区 是一种数据库优化的技术&#xff0c;它允许将一个大的表、索引或其子集分割成多个较小的、更易于管理的片段&#xff0c;这些片段称为“分区”。每个分区都可以独立于其他分区进行存储、备份、索引和其他操作。这种技术主要…

STM32智能楼宇照明系统教程

目录 引言环境准备智能楼宇照明系统基础代码实现&#xff1a;实现智能楼宇照明系统 4.1 数据采集模块 4.2 数据处理与控制模块 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;楼宇照明管理与优化问题解决方案与优化收尾与总结 1. 引言 智能楼宇照明系…

OSI 七层模型与五层模型

OSI&#xff08;开放系统互连&#xff09;七层模型和五层模型是描述计算机网络协议的两种不同层次划分方法。两者用于帮助理解和设计网络协议&#xff0c;但它们在层次划分上有所不同。

java.sql.SQLException: Unknown system variable ‘query_cache_size‘【Pyspark】

1、问题描述 学习SparkSql中&#xff0c;将spark中dataframe数据结构保存为jdbc的格式并提交到本地的mysql中&#xff0c;相关代码见文章末尾。 运行代码时报出相关配置文件错误&#xff0c;如下。 根据该报错&#xff0c;发现网络上多数解决方都是基于java开发的解决方案&a…

创建鸿蒙手机模拟器(HarmonyOS Emulator)

文 | Promise Sun 一.前提条件&#xff1a; 鸿蒙项目开发需要使用模拟器进行开发测试&#xff0c;但目前想在DevEco Studio开发工具中使用模拟器就必须到华为官网进行报名申请&#xff0c;参加“鸿蒙模拟器&#xff08;HarmonyOS Emulator&#xff09;Beta活动申请”。 申请审…

Macbook pro插移动硬盘没反应,Macbook pro移动硬盘读不了怎么办 macbook插移动硬盘后无法使用

为了弥补Macbook pro硬盘容量的缺失&#xff0c;我们有时候会使用到外接硬盘或移动硬盘。一般来说&#xff0c;这些硬盘都是即插即用的&#xff0c;可能部分要安装插件。不过&#xff0c;在一些特殊情况下&#xff0c;也会遇到插硬盘没反应等问题。本文会给大家解答Macbook pro…

STM32第二十一课:FreeRTOS事件组软件定时器

目录 一、事件组1.事件组创建2.事件组置位3.事件组等待 二、软件定时器1.软件定时器创建2.软件定时器执行3.例程代码 一、事件组 本质上是任务同步&#xff0c;但比二值信号量优秀的是可以一对多。 我的理解&#xff1a;事件组就是标志位的集合&#xff0c;将多个标志位放到一个…

Raw Socket(二)循环队列收发数据

完整代码在&#xff1a; 添加链接描述 其中tcp_handshake文件夹是实现TCP三次握手的demo。 完整代码参考&#xff1a; https://github.com/praveenkmurthy/Raw-Sockets 代码实现基于raw socket的TCP协议&#xff0c;发送http请求包并接收回包&#xff0c;…

【自学安全防御】二、防火墙NAT智能选路综合实验

任务要求&#xff1a; &#xff08;衔接上一个实验所以从第七点开始&#xff0c;但与上一个实验关系不大&#xff09; 7&#xff0c;办公区设备可以通过电信链路和移动链路上网(多对多的NAT&#xff0c;并且需要保留一个公网IP不能用来转换) 8&#xff0c;分公司设备可以通过总…

mitmproxy介绍及使用

mitmproxy介绍 mitmproxy又名中间人攻击代理&#xff0c;是一个抓包工具&#xff0c;类似于WireShark、Filddler&#xff0c;并且它支持抓取HTTP和HTTPS协议的数据包&#xff0c;只不过它是一个控制台的形式操作。另外&#xff0c;它还有两个非常有用的组件&#xff0c;一个mi…

openlayers WebGLPoints图层应用(光环、光晕扩散收缩)

本篇介绍一下使用 openlayers WebGLPoints图层应用&#xff08;光环、光晕扩散收缩&#xff09; 1 需求 WebGL渲染的光环、光晕扩散收缩 2 分析 WebGLPoints图层应用ol/expr/expression 的简单使用官网解释 WebGLPoints 的 style 属性比较多&#xff08;基本都是图标、填充…

CSS选择器(1)

以内部样式表编写CSS选择器&#xff0c;其主要编写在<head></head>元素里&#xff0c;通过<style></style>标签来定义内部样式表。 基本语法为&#xff1a; 选择器{ 声明块 } 声明块&#xff1a;是由一对大括号括起来&#xff0c;声明块中是一个一个的…

03MFC画笔/画刷/画椭圆/圆/(延时)文字

文章目录 画实心矩形自定义画布设计及使用连续画线及自定义定义变量扇形画椭圆/圆输出颜色文本定时器与定时事件画实心矩形 自定义画布设计及使用 连续画线及自定义定义变量 扇形 画椭圆/圆 输出颜色文本

杰发科技AC7801 —— __attribute__指定地址存储常量

const uint8_t usFlashInitVal[] __attribute__((at(0x08002800))) {0x55,0x55,0x55,0x55,0x55};//定位在flash中&#xff0c;0x00030000开始的6个字节信息固定 注意7801的地址在8000000之后 如地址选0x00000800烧录时候报错 不知道是不是atclinktool的bug&#xff0c;使用_…

缓存穿透,缓存雪崩,使用互斥锁解决缓存击穿

20240716学习redis 一、缓存穿透1. isNotBlank()方法和isNotEmpty()方法的区别2. 缓存穿透3. 缓存雪崩4. 缓存击穿的解决5 ctrlaltT&#xff0c;可以快速生成包围方式&#xff1a;6 //模拟重建延时7. 代码 &#xff08;使用互斥锁&#xff09; 一、缓存穿透 1. isNotBlank()方…

Linux系统编程-线程同步详解

线程同步是指多个线程协调工作&#xff0c;以便在共享资源的访问和操作过程中保持数据一致性和正确性。在多线程环境中&#xff0c;线程是并发执行的&#xff0c;因此如果多个线程同时访问和修改共享资源&#xff0c;可能会导致数据不一致、竞态条件&#xff08;race condition…