数据结构-插入排序

插入排序

插入排序的三种常见方法:

直接插入排序、折半插入排序、希尔排序。

数据存储结构

因为我们是用的是C语言来实现算法,因此我们需要创建一个结构体,用来存放初始数据。

结构体定义如下:

#define MAX 100
typedef int KeyType;
typedef struct{
	KeyType key;
}RecordType;
typedef struct{
	RecordType R[MAX+1];
	int length;
}OrderList;

示例数据

 

其中data[0]置为0,用来表示哨兵单元。

直接插入排序

基本思想

当插入第i个记录时,前面的R[1]....R[i-1]已经排好序,这时用R[i]依次与前面的关键字比较,直到找

到合适的位置,随后插入。

代码实现

OrderList InsertSort(OrderList L)	//直接插入排序 
{
	int i,j;
	for(i=2;i<=10;i++){
		L.R[0] = L.R[i];	//L[0]做哨兵单元,同时也用来存放当前i位置记录大小. 
		j = i - 1;		//从i单元的前一个单元开始比较. 
		while(L.R[0].key<L.R[j].key){		//升序 
			L.R[j+1] = L.R[j];		//记录依次后移,其中最前面的记录永远会存在连续的两个. 
			j = j - 1;			//j需要前移继续比较. 
		}
		L.R[j+1] = L.R[0];		//j+1为合适的位置. 
	}
	return L;
}

验证

复杂度

时间复杂度为:O(_N{2})

空间复杂度一直为:O(1)

折半插入排序

基本思想

折半插入排序跟前面的折半查找有同曲异工之妙,其中在查找的时候不再是顺序查找,而是折半查

找,但是在数据移动的过程中,仍然是顺序移动下来。

代码实现

OrderList BinsertSort(OrderList L)		//折半插入排序 
{
	int i,j,low,high,mid;
	for(i=2;i<=L.length;i++){
		L.R[0] = L.R[i];
		low = 1;
		high = i - 1;		//上界应该为i单元的前一个单元位置 
		while(low <= high){		
			mid = (low+high) / 2;
			if(L.R[0].key < L.R[mid].key)
				high = mid - 1;
			else
				low = mid + 1;
		}	//待插入的位置一定是low的位置, 
		for(j=i-1;j>=low;j--)		//i单元前面的所有单元依次后移. 
			L.R[j+1] = L.R[j];
		L.R[low] = L.R[0];		//插入单元 
	}
	return L;
}

验证

复杂度

若待排序列为正序,则时间复杂度为:O(N)

若待排序列为逆序,则时间复杂度为:O(_N{2})

空间复杂度一直为:O(1)

希尔排序

希尔排序又叫做“缩小增量排序”。

基本思想

先将整个记录序列分割成若干个子序列,分别进行直接插入排序,在整个序列中的记录“基本有序”

时,再对全体记录进行一次直接插入排序。

其中,子序列并不是进行简单的分割,而是将某个增量d的记录组成一个子序列,让增量d逐步缩

短,直到d=1为止。

d的选取有很多种方法,这里只简单说明最基本的一种(足以应对绝大多数情景):

d = [n/2]--------->d = [d/2]

下面我们给出一个例子:

假定有一个数据序列为:{5,9,12,2,8,15}

我们来看看希尔排序的一个完整过程:

1.d = [6/2] = 3

将整个序列分为三个子序列:{5,2}、{9,8}、{12,15}。

对三个子序列分别进行直接插入排序,得到新的三个子序列:

{2,5}、{8,9}、{12,15}

由这三个子序列拼凑成一个新的序列为:

{2,8,12,5,9,15}

2.d = [3/2] = 1

此时d = 1,所以直接对整个序列{2,8,12,5,9,15}进行一次直接插入排序,即可获得最终结果。

代码实现

OrderList ShellSort(OrderList L)
{
	int i,j,d;
	RecordType tmp;
	for(d=L.length/2;d>0;d/=2){		//d为本趟希尔排序的增量 
		for(i=d+1;i<=L.length;i++){
			tmp = L.R[i];		//保存待插入单元 
			j = i - d;		//j是与i间隔为d的前一个单元 
			while(j>=1&&tmp.key<L.R[j].key){	
				L.R[j+d] = L.R[j];		//R[j]必须后移d个位置,因为比较单元间相隔d 
				j = j - d;
			}
			L.R[j+d] = tmp; 
		}
	}
	return L;
}

验证

复杂度

时间复杂度为:O(^{N^{1.3}})

空间复杂度一直为:O(1)

所有代码

#include<stdio.h>
#define MAX 100
typedef int KeyType;
typedef struct{
	KeyType key;
}RecordType;
typedef struct{
	RecordType R[MAX+1];
	int length;
}OrderList;

OrderList InsertSort(OrderList L)	//直接插入排序 
{
	int i,j;
	for(i=2;i<=10;i++){
		L.R[0] = L.R[i];	//L[0]做哨兵单元,同时也用来存放当前i位置记录大小. 
		j = i - 1;		//从i单元的前一个单元开始比较. 
		while(L.R[0].key<L.R[j].key){		//升序 
			L.R[j+1] = L.R[j];		//记录依次后移,其中最前面的记录永远会存在连续的两个. 
			j = j - 1;			//j需要前移继续比较. 
		}
		L.R[j+1] = L.R[0];		//j+1为合适的位置. 
	}
	return L;
}

OrderList BinsertSort(OrderList L)		//折半插入排序 
{
	int i,j,low,high,mid;
	for(i=2;i<=L.length;i++){
		L.R[0] = L.R[i];
		low = 1;
		high = i - 1;		//上界应该为i单元的前一个单元位置 
		while(low <= high){		
			mid = (low+high) / 2;
			if(L.R[0].key < L.R[mid].key)
				high = mid - 1;
			else
				low = mid + 1;
		}	//待插入的位置一定是low的位置, 
		for(j=i-1;j>=low;j--)		//i单元前面的所有单元依次后移. 
			L.R[j+1] = L.R[j];
		L.R[low] = L.R[0];		//插入单元 
	}
	return L;
}

OrderList ShellSort(OrderList L)
{
	int i,j,d;
	RecordType tmp;
	for(d=L.length/2;d>0;d/=2){		//d为本趟希尔排序的增量 
		for(i=d+1;i<=L.length;i++){
			tmp = L.R[i];		//保存待插入单元 
			j = i - d;		//j是与i间隔为d的前一个单元 
			while(j>=1&&tmp.key<L.R[j].key){	
				L.R[j+d] = L.R[j];		//R[j]必须后移d个位置,因为比较单元间相隔d 
				j = j - d;
			}
			L.R[j+d] = tmp; 
		}
	}
	return L;
}

int main()
{
	OrderList sample;
	sample.length = 10;
	int i,data[11]={0,5,8,4,12,35,6,8,67,64,100};
	for(i=1;i<11;i++)
		sample.R[i].key = data[i];
	sample = ShellSort(sample);
	for(i=1;i<11;i++)
		printf("%d ",sample.R[i].key);
	return 0;
}

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

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

相关文章

Spring Framework IOC依赖查找 - 按类型查找解析

目录 在Spring框架中&#xff0c;控制反转&#xff08;IoC&#xff09;是一种设计模式&#xff0c;它通过将对象的创建和管理交给容器来实现。依赖查找是IoC的一部分&#xff0c;它允许你从容器中查找所需的依赖项。按类型进行依赖查找是其中的一种方式&#xff0c;今天来讲Spr…

笔记57:双向循环神经网络

本地笔记地址&#xff1a;D:\work_file\DeepLearning_Learning\03_个人笔记\3.循环神经网络\第9章&#xff1a;动手学深度学习~现代循环神经网络 a a a a a a a a a a a a

动态页面调研及设计方案

文章目录 vue2 动态表单、动态页面调研一、form-generator二、ng-form-element三、Variant Form四、form-create vue2 动态表单、动态页面调研 一、form-generator 预览&#xff1a;https://mrhj.gitee.io/form-generator/#/ Vue2 Element UI支持拖拽生成表单不支持其他组件…

(六)、基于 LangChain 实现大模型应用程序开发 | 基于知识库的个性化问答 (文档分割 Splitting)

在上一章中&#xff0c;我们刚刚讨论了如何将文档加载到标准格式中&#xff0c;现在我们要谈论如何将它们分割成较小的块。这听起来可能很简单&#xff0c;但其中有很多微妙之处会对后续工作产生重要影响。 文章目录 1、为什么要做文档分割&#xff1f;2、文档分割方式3、基于…

手机app、pc客户端(芯象推送到wvp视频平台)

手机app&#xff08;芯象推送到wvp视频平台&#xff09; 下载安装 进入苹果应用商店&#xff0c;搜索芯象&#xff0c;点击下载&#xff0c;下载成功之后点击打开 注册账号进行登录&#xff0c;下图是主界面&#xff0c;点击开始直播进入直播配置界面 推流直播 选择本地推流&a…

IDEA调用接口超时,但Postman可成功调用接口

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

SpringCloud微服务通信两种方式Feign和Dubbo:Feign基本使用、自定义配置、使用优化;Dubbo基本实现

RestTemplate存在的问题 代码可读性差&#xff0c;编程体验不统一参数复杂&#xff0c;URL难以维护 Feign远程调用 Feign简介 ​ Feign是SpringCloud提供的一个声明式的伪Http客户端&#xff0c;它使得调用远程服务就像调用本地服务一样简单&#xff0c;只需要创建一个接口…

【广州华锐互动】VR虚拟现实技术助力太空探险:穿越时空,探索宇宙奥秘

随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术已经逐渐走进我们的生活。在教育领域&#xff0c;VR技术的应用也日益广泛&#xff0c;为学生提供了更加生动、直观的学习体验。本文将以利用VR开展太空探险学习为主题&#xff0c;探讨如何将这一先进技术…

【数据库】你听说过矢量数据库吗?

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️其他领域】 文章目录 前言什么是向量/矢量数据库嵌入模型使用向量数据库的优势与传统数据库的对比其他方面 AWS 如何支持您的矢量数据库需求&#xff1f;Amazon OpenSearch ServiceAmazon Aurora Pos…

毕业设计JSP 2384网上diy蛋糕店管理系统【程序源码+讲解视频+调试运行】

一、摘要 本文将介绍一个功能全面、易于使用的网上DIY蛋糕店管理系统。该系统包括用户和管理员两种用户&#xff0c;每种用户都有相应的功能模块。系统实现了网站首页、用户注册/登录、蛋糕展示、综合排行、购物车、蛋糕DIY和用户中心等功能&#xff0c;同时管理员还可以进行管…

Java —— 抽象类和接口

目录 1. 抽象类 1.1 抽象类概念 1.2 抽象类语法与特性 1.3 抽象类的作用 2. 接口 2.1 接口的概念 2.2 接口的语法规则与特性 2.3 实现多个接口(解决多继承的问题) 2.4 接口间的继承 2.5 抽象类和接口的区别 2.6 接口的使用实例 2.7 Clonable 接口和深拷贝 2.7.1 Cloneable接口 …

【前端学java】java中的Object类(8)

往期回顾&#xff1a; 【前端学java】JAVA开发的依赖安装与环境配置 &#xff08;0&#xff09;【前端学 java】java的基础语法&#xff08;1&#xff09;【前端学java】JAVA中的packge与import&#xff08;2&#xff09;【前端学java】面向对象编程基础-类的使用 &#xff08…

归并排序详解:递归实现+非递归实现(图文详解+代码)

文章目录 归并排序1.递归实现2.非递归实现 归并排序 时间复杂度&#xff1a;O ( N * logzN ) 每一层都是N,有log2N层空间复杂度&#xff1a;O&#xff08;N&#xff09;&#xff0c;每个区间都会申请内存&#xff0c;最后申请的数组大小和array大小相同稳定性&#xff1a;稳定 …

Linux从 全栈开发 centOS 7 到 运维

Linux从 全栈开发centOS 7 到 运维 一 Linux 入门概述1.1 操作系统1.2 Linux 简介1.3 Linux 系统组成1.4 Linux 发行版1.4 Linux 应用领域1.5 Linux vs Windows 二 环境搭建【狂神说Java】服务器购买及宝塔部署环境说明为什么程序员都需要一个自己的服务器服务器如何购买买完服…

中国农业开启加速度,龙江农业迎来黄金期

​ “中国下一个发展动力将是大农业&#xff0c;而黑龙江大农业正在成为世界农业中心。” 在前不久举办的首届龙商大会暨中国&#xff08;黑龙江&#xff09;国际绿色食品产业高质量发展论坛&#xff08;下文简称“论坛”&#xff09;上&#xff0c;大北农科技集团股份有限公…

OpenCV快速入门:直方图、掩膜、模板匹配和霍夫检测

文章目录 前言一、直方图基础1.1 直方图的概念和作用1.2 使用OpenCV生成直方图1.3 直方图归一化1.3.1 直方图归一化原理1.3.2 直方图归一化公式1.3.3 直方图归一化代码示例1.3.4 OpenCV内置方法&#xff1a;normalize()1.3.4.1 normalize()方法介绍1.3.4.2 normalize()方法参数…

Javaweb之Ajax的详细解析

1.1 Ajax介绍 1.1.1 Ajax概述 我们前端页面中的数据&#xff0c;如下图所示的表格中的学生信息&#xff0c;应该来自于后台&#xff0c;那么我们的后台和前端是互不影响的2个程序&#xff0c;那么我们前端应该如何从后台获取数据呢&#xff1f;因为是2个程序&#xff0c;所以…

前缀和(c++,超详细,含二维)

前缀和与差分 当给定一段整数序列a1,a2,a3,a4,a5…an; 每次让我们求一段区间的和&#xff0c;正常做法是for循环遍历区间起始点到结束点&#xff0c;进行求和计算&#xff0c;但是当询问次数很多并且区间很长的时候 比如&#xff0c;10^5 个询问和10^6区间长度&#xff0c;相…

Java语法基础

回顾 1、了解编程语言 2、编程语言分类 ​ 机器语言、汇编语言、高级语言 3、了解java ​ 跨平台&#xff08;.class文件&#xff09; .java&#xff08;源文件&#xff09; ​ .java ----编译---->.class 4、jdk 、jre、jvm 5、开发 写代码 eclipse idea 记事本 …

企业级SSD还是一个巨大的蓝海~

根据Allied Market Research市场分析报告显示&#xff0c;2020 年全球企业级 SSD 市场规模为 178.5 亿美元&#xff0c;预计到 2030 年将达到 468.9 亿美元&#xff0c;2021 年至 2030 年的复合年增长率为 10.2%。 扩展阅读&#xff1a;华为展望&#xff5c;2030年数据中心存储…