算法之插入排序及希尔排序(C语言版)

news2024/12/25 0:20:57

我们来实现上述排序

一.插入排序.

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

CSDN这个链接有我之前写的直接插入排序

今天我们来实现广义上的插入排序:

我直接写出来,会在里面写注释

void Insertsort(int* arr, int n)//arr数组,n元素个数
{
	//我们用升序排列
	for (int i = 0; i < n-1; i++)//循环n次
	{
		int end = i;//将i的值赋给end,方便将其数值改变而不影响循环
		int tmp = arr[end + 1];//由于升序,我们要提前保存要排序的数
		//这里默认前i个数是已排好的,即end
		while (end >= 0)
		{
			if (arr[end] > tmp)//arr[end]与arr[end+1]比较
			{
				arr[end + 1] = arr[end];//满足条件赋值
				end--;//继续向前排列
			}
			else
			{
				break;//不满足条件退出循环
			}
		}
		arr[end + 1] = tmp;//将保存的数值赋给留出的位置
	}
}

我们排一个数组试试:
 

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
void Insertsort(int* arr, int n)//arr数组,n元素个数
{
	//我们用升序排列
	for (int i = 0; i < n-1; i++)//循环n次
	{
		int end = i;//将i的值赋给end,方便将其数值改变而不影响循环
		int tmp = arr[end + 1];//由于升序,我们要提前保存要排序的数
		//这里默认前i个数是已排好的,即end
		while (end >= 0)
		{
			if (arr[end] > tmp)//arr[end]与arr[end+1]比较
			{
				arr[end + 1] = arr[end];//满足条件赋值
				end--;//继续向前排列
			}
			else
			{
				break;//不满足条件退出循环
			}
		}
		arr[end + 1] = tmp;//将保存的数值赋给留出的位置
	}
}
void Print(int* arr, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{
	int arr[] = { 2,4,6,8,0,1,3,5,7,9 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	Insertsort(arr, sz);
	Print(arr, sz);

}

结果:

当然我们也可以用降序来排:

void Insertsort(int* arr, int n)//arr数组,n元素个数
{
	//我们用升序排列
	for (int i = 0; i < n-1; i++)//循环n次
	{
		int end = i;//将i的值赋给end,方便将其数值改变而不影响循环
		int tmp = arr[end + 1];//由于升序,我们要提前保存要排序的数
		//这里默认前i个数是已排好的,即end
		while (end >= 0)
		{
			if (arr[end] < tmp)//arr[end]与arr[end+1]比较,改变<,>符号即可
			{
				arr[end + 1] = arr[end];//满足条件赋值
				end--;//继续向前排列
			}
			else
			{
				break;//不满足条件退出循环
			}
		}
		arr[end + 1] = tmp;//将保存的数值赋给留出的位置
	}
}

上题数组的结果(用降序排列):

我们接下来看看其时间复杂度:

我们只考虑最坏的情况:

假设 n=1:外层1次,内层1次

        n=2:外层2次,内层最坏2次

        n=3:外层3次,内层最坏3次

        n=n:外层n次,内层最坏n次

因此时间复杂度为:O(N*N)=O(N^2);

二.插入排序进阶----希尔排序.

又叫递减增量排序算法。

思想:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序

希尔排序主要分两步:1.预排序  2.插入排序

预排序:分组排间隔为gap是一组。

假设gap == 5

对组间隔为gap的预排序,gap由大变小,gap越大,大的数可以越快的到后面,小的数可以越快的到前面,gap越大,预排完越不接近有序
gap越小,越接近有序,gap == 1时就是直接插入排序

我们直接实现,在插入排序上改:

void Shellsort(int* arr, int n)
{
	int gap = n;//将n的值赋值一份给gap,便于后续对gap给值划分
	while (gap > 1)
	{
		//法一:gap/2为单位
		gap = gap / 2;//gap的值以二分之一不断划分,最后得到gap=1进行插入排序
		//gap/3为单位
		//gap = gap / 3 + 1;//gap的值以三分之一不断划分,最后加+1得到gap=1进行插入排序
		//gap>1时进行预排序
		//gap=1时进行插入排序
		for (int i = 0; i < n - gap; i++)//i<n-gap:把间隔为gap的多组数据同时排
		{
			//下面操作和插入排序大体相同,但注意不再时加减1;而是以gap为单位!!!
			int end = i;
			int tmp = arr[end + gap];
			while (end >= 0)
			{
				if (arr[end] > tmp)
				{
					arr[end + gap] = arr[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			arr[end + gap] = tmp;
		}
	}
}

继续实现上面那个数组的排序:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
void Shellsort(int* arr, int n)
{
	int gap = n;//将n的值赋值一份给gap,便于后续对gap给值划分
	while (gap > 1)
	{
		//法一:gap/2为单位
		gap = gap / 2;//gap的值以二分之一不断划分,最后得到gap=1进行插入排序
		//gap/3为单位
		//gap = gap / 3 + 1;//gap的值以三分之一不断划分,最后加+1得到gap=1进行插入排序
		//gap>1时进行预排序
		//gap=1时进行插入排序
		for (int i = 0; i < n - gap; i++)//i<n-gap:把间隔为gap的多组数据同时排
		{
			//下面操作和插入排序大体相同,但注意不再时加减1;而是以gap为单位!!!
			int end = i;
			int tmp = arr[end + gap];
			while (end >= 0)
			{
				if (arr[end] > tmp)
				{
					arr[end + gap] = arr[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			arr[end + gap] = tmp;
		}
	}
}
void Print(int* arr, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{
	int arr[] = { 2,4,6,8,0,1,3,5,7,9 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	Shellsort(arr, sz);
	Print(arr, sz);

}

结果:

上面这是升序的,相信降序的大家都会了。没错,和插入排序改变之处相同。

接下来我们讨论其时间复杂度:

gap = gap / 2;// logN
//gap = gap / 3 + 1;// 1og3N 以3为底数的对数
for (int i = 0; i < n - gap; i++)
{
	// gap > 1时都是预排序 接近有序
	// gap == 1时就是直接插入排序 有序
	// gap很大时,下面预排序时间复杂度0(N)
	// // gap很小时,数组已经很接近有序了,这时差不多也是(N)
	int end = i;
	int tmp = arr[end + gap];
	while (end >= 0)
	{
		if (arr[end] > tmp)
		{
			arr[end + gap] = arr[end];
			end -= gap;
		}
		else
		{
			break;
		}
	}
	arr[end + gap] = tmp;
}

因此,其时间复杂度为:O(N*logN),平均的时间复杂度是0(N*1.3)

读者可能会想这个希尔排序是三层循环,而插入排序才两层循环,不可能出现其算法更优越啊!

但实际上,确实是希尔排序快,而且快了不止一点。

假设用10万个数据,我们对比发现希尔排序要少排非常多次。

InsertSort:1616ms
ShellSort:12ms

这是一个相同数据检测出来两者的时间差距,可见两者的差距有多大,希尔牛逼!

希尔排序缺点:

希尔排序并不只是相邻元素的比较,有许多跳跃式的比较,难免会出现相同元素之间的相对位置发生变化,所以希尔排序是不稳定的算法。

最后,我会不间断的更新其他排序,希望大家多多支持!

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

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

相关文章

【小布_ORACLE】Part11-1--RMAN Backups笔记

Oracle的数据备份于恢复RMAN Backups 学习第11章需要掌握&#xff1a; 一.RMAN的备份类型 二.使用backup命令创建备份集 三.创建备份文件 四.备份归档日志文件 五.使用RMAN的copy命令创建镜像拷贝 文章目录 Oracle的数据备份于恢复RMAN Backups1.RMAN Backup Concepts&#x…

安卓开发学习---kotlin版---笔记(一)

Hello word 前言&#xff1a;上次学习安卓&#xff0c;学了Java开发&#xff0c;简单的搭了几个安卓界面。这次要学习Kotlin语言&#xff0c;然后开发安卓&#xff0c;趁着还年轻&#xff0c;学点新东西&#xff0c;坚持~ 未来的你会感谢现在努力的你~ 主要学习资料&#xff1a…

使用Python进行帧提取及指定帧插入实现文本隐写(CTF杂项出题方向)

视频是由一系列连续的图像帧组成的&#xff0c;每一帧都是视频的静止画面。这些帧以一定的速率播放&#xff0c;就形成了运动的视频。以下是视频帧的一些基本概念&#xff1a; 帧率&#xff08;Frame Rate&#xff09;&#xff1a; 帧率表示每秒播放的图像帧数量。通常以“帧/秒…

性能自动化测试?

一、思考❓❔ 1.什么是性能自动化测试? 性能 系统负载能力超负荷运行下的稳定性系统瓶颈 自动化测试 使用程序代替手工提升测试效率性能自动化 使用代码模拟大批量用户让用户并发请求多页面多用户并发请求采集参数&#xff0c;统计系统负载能力生成报告 2.Python中的性能…

【JavaEE初阶】——Linux 基本使用和 web 程序部署(下)

文章目录 前言一、Linux 常用命令 1.1 ls 命令 1.2 pwd 命令 1.3 cd 命令 1.4 touch 命令 1.5 cat 命令 1.6 mkdir 命令 1.7 rm 命令 1.8 cp 命令 1.9 mv 命令 1.10 man 命令 1.11 less 命令 1.12 head 命令 1.13 tail 命…

leetcode LCR24反转单链表

反转单链表 题目描述 题目分析 先来说迭代的思想&#xff1a; 上面next cur->next应该放在cur->next pre前面执行&#xff0c;这里笔误 再来说递归的思想&#xff1a; 题目代码 这个代码里面我加了我自己写的测试数据&#xff0c;自己可以去找对应的部分&#xff0c…

Charles下载安装及配置之Mac

因工作需要用到抓包工具&#xff0c;但Fiddler不能在mac上使用&#xff0c;所以找到了Charles&#xff0c;Charles其实是一款代理服务器&#xff0c;通过过将自己设置成系统&#xff08;电脑或者浏览器&#xff09;的网络访问代理服务器&#xff0c;然后截取请求和请求结果达到…

集结!Milvus 老友汇 · 线下 Meetup 来袭

AGI 时代&#xff0c;当“大模型的记忆体”——向量数据库&#xff0c;邂逅 Cloud-Native 的数据管理平台及 AI-Native 的应用&#xff0c;会迸发出怎样的化学反应&#xff1f; 12 月 9 日&#xff01;上海&#xff01;Milvus 社区携手 KubeBlocks 社区&#xff0c;集结来自两大…

可视化文件编辑与SSH传输神器WinSCP如何公网远程本地服务器

可视化文件编辑与SSH传输神器WinSCP如何公网远程本地服务器 文章目录 可视化文件编辑与SSH传输神器WinSCP如何公网远程本地服务器1. 简介2. 软件下载安装&#xff1a;3. SSH链接服务器4. WinSCP使用公网TCP地址链接本地服务器5. WinSCP使用固定公网TCP地址访问服务器 1. 简介 …

OpenCvSharp从入门到实践-(05)通道

目录 1、拆分通道 1.1、实例1-拆分一副BGR图像的通道 1.2、实例2-拆分一副HSV图像的通道 2、合并通道 2.1 实例3-合并通道的顺序不同&#xff0c;图像的显示效果也不通 实例4-合格H通道图像、S通道图像、V通道图像 3、综合运用拆分通道和合并通道 2.2、实例5-只把H通道的…

Windows10免安装PostgreSQL

1. PostgreSQL简介2. 下载3. 安装环境4. 安装 4.1. 初始化数据库4.2. 启动数据库4.3. 注册服务4.3. 卸载服务 1. PostgreSQL简介 PostgreSQL 是一种特性非常齐全的自由软件的对象-关系型数据库管理系统&#xff0c;是以加州大学计算机系开发的 POSTGRES 4.2版本为基础的对象关…

羽隔已就之图像处理之BP神经网络入门

小y最近非常忙&#xff0c;这一年来&#xff0c;活很多&#xff0c;一直在加班、出差&#xff0c;也没好好休息过。最近在武汉出差一个多月了&#xff0c;项目逐渐完结&#xff0c;有点闲时间了&#xff0c;回首望&#xff0c;这一年设定的很多目标都没完成。 还记得&#xff0…

智慧博物馆视频监控系统设计,可视化AI智能分析技术助力博物馆多维度监管

一、背景与需求 博物馆视频智能监控系统是智慧博物馆建设的重要组成部分&#xff0c;传统的博物馆视频监控系统以模拟系统架构为主&#xff0c;存在监管效率低、各个系统独立运作形成数据孤岛、以“事后补救”为主要监管手段等管理弊病&#xff0c;无法满足互联网高速发展背景…

如何获取高质量的静态住宅IP代理?常见误区与注意事项

静态住宅IP代理在今天的网络营销领域扮演着至关重要的角色&#xff0c;静态住宅IP代理以其稳定性和高匿名性&#xff0c;为互联网业务提供了一个安全的执行环境。通过模拟真实用户的网络行为&#xff0c;这些IP代理降低了企业在网络营销活动中被识别和封禁的风险。它保护了企业…

Postgresql数据库运维统计信息

如果需要使用以下运维信息&#xff0c;需要如下几步 修改postgresql.conf文件 #shared_preload_libraries # (change requires restart)shared_preload_libraries pg_stat_statements重启数据库创建扩展 CREATE EXTENSION IF NOT EXISTS pg_stat_statements;1. 统计信息…

java: Internal error in the mapping processor: java.lang.NullPointerException

启动java项目出错&#xff0c;其他人工程没有问题&#xff0c;别着急。 java: Internal error in the mapping processor: java.lang.NullPointerException at org.mapstruct.ap.internal.processor.DefaultVersionInformation.createManifestUrl(DefaultVersionInformation.j…

微信如何养号?

目前导致微信封号的几点原因如下&#xff1a; 1.使用虚拟定位软件&#xff0c;进行附近人任务&#xff0c;频繁的切换ip&#xff0c;极易被判定微信被盗,对其封号 2.频发的群发骚扰消息&#xff0c;朋友圈发送过于频繁&#xff0c;给别人造成骚扰及其投诉 3.和微信好友聊天涉…

Python接口自动化测试 ---Allure报告使用详解

这一节主要是记录allure的内容以及用法&#xff0c;怎么让他生成一个完整的想要的报告。 allure生成的报告和其他五花八门的报告对比了一下&#xff0c;它的可读性是最好、最直观的。这不仅仅是我想要的效果&#xff0c;也是很多小伙伴想要的结果&#xff0c;毕竟这是给领导看…

JSON详细教程

&#x1f60a;JSON详细教程 &#x1f6a9;JSON简介☃️JSON语法规则&#x1f50a;JSON和JavaScript对象的区别 ☃️JSON数据类型字符串&#x1f50a;数字&#x1f50a;布尔值&#x1f50a;数组&#x1f50a;对象&#x1f50a;Null ☃️JSON对象&#x1f50a;访问JSON对象的值&a…

Linux脚本sed命令

目录 一. sed命令定义 二. sed命令选项 三. sed语法选项 四. 案例解释 1. 打印奇数或偶数行 2. 打印固定行数 3. 打印包含字符的行 4. 打印特定字符首尾行 5. 删除固定行数 6. 删除特定字符行 7. 插入在固定行中 8. 替换规定行数 9. 使用变量 10. 多点编辑 11. 分…