排序算法——上

news2024/11/15 13:49:52

一、冒泡排序:

1、冒泡排序算法的思想

我们从左边开始把相邻的两个数两两做比较,当一个元素大于右侧与它相邻的元素时,交换它们之间位置;反之,它们之间的位置不发生变化。冒泡排序是一种稳定的排序算法。

2、代码实现:

void BubbleSort(int* a, int n)
{
	for (int i = 1; i < n; i++)
	{
		for (int j = 0; j < n - i; j++)
		{
			if (a[j] > a[j + 1])
			{
				swap(&a[j], &a[j + 1]);
			}
		}
	}
}

冒泡排序需要有两层循环,无论数组是否排好序,都会完成这两层循环,对于最差的情况,比如[9,8,7,6,5,4],对其进行升序排序,这两层循环必不可少;但是对于[9,1,2,3,4,5]这种情况,第一遍循环结束后,整个数组就已经是升序排列的了,但是普通的冒泡排序还会继续进行循环遍历比较,这就对做了不少无用功。所以需要设置一个排序完成的标志,如果排序已经完成,就没必要再继续循环遍历了,直接跳出循环。

优化版本:

void BubbleSort(int* a, int n)
{
	for (int i = 1; i < n; i++)
	{
		int flag = 0;
		for (int j = 0; j < n - i; j++)
		{
			if (a[j] > a[j + 1])
			{
				swap(&a[j], &a[j + 1]);
				flag = 1;
			}
		}
		if (flag == 0)
		{
			break;
		}
	}
}

 二、插入排序

1、直接插入排序:

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

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

单趟:

int end = i;
int tmp = a[i + 1];
while (end >= 0)
{
	if (a[end] > tmp)
	{
		a[end+1] = a[end];
		end--;
	}
	else
	{
		break;
	}
	a[end+1] = tmp;
}

这里有些同学可能会这样去写:

int end = i;
int tmp = a[i + 1];
while (end >= 0)//如果写为>0则最后一个数据比较不了。
{
	if (a[end] > tmp)
	{
		a[end+1] = a[end];
		end--;
	}
}
//最后出去时end为-1
a[end+1] = tmp;

其实这样会造成不必要的比较,因为前面的数据已经排好序,所以当if条件不满足时,一定排好了序,只需将后一个数据放在end位置即可;

很多人会这么写:

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

但是实际上这样写会造成数组越界访问,[0, n-2]是最后一组[0,end]有序 end+1位置的值插入[0,end],保持有序

void InsertSort(int* a, int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		// [0, n-2]是最后一组
		// [0,end]有序 end+1位置的值插入[0,end],保持有序
		int end = i;
		int tmp = a[i + 1];
		while (end >= 0)
		{
			if (a[end] > tmp)
			{
				a[end+1] = a[end];
				end--;
			}
			else
			{
				break;
			}
			a[end+1] = tmp;
		}
	}
}

 2、希尔排序

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

 我们先尝试第一趟中红色组的排序:

//对红色组
int gap = 5;
for (int i = 0; i < n - gap; i+=gap)
{
	int end = i;
	int tmp = a[i + gap];
	while (end >= 0)
	{
		if (tmp < a[end])
		{
			a[end + gap] = a[end];
			end -= gap;
		}
		else
		{
			break;
		}
		a[end+gap] = tmp;
	}
}

同理不可写为<n,因为可能造成数组越界访问。(我们不难发现其是插入排序的一种变形);

那么我们对第一趟排序就非常好写了:

1、分组排序

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

2、同时排序:

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

虽然两个循环层数不一样但是效率是一模一样的(时间复杂度不能单看循环层数判断)。

我们知道:

gap > 1时是预排序

gap == 1时是插入排序

所以我们要想办法通过调整gap来实现插入排序:

所以每次调整为gap/3+1。

void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap > 1)//这不可写为》=1,因为如果为1,则最后一次进去还是1,相当于多排了一次,浪费
	{
		gap = gap / 3 + 1;
		for (int i = j; i < n - gap; i++)
		{
			int end = i;
			int tmp = a[end + gap];
			while (end >= 0)
			{
				if (tmp < a[end])
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			a[end + gap] = tmp;
		}
	}
	
}

3、希尔排序时间复杂度的简单推理:

 

三、选择排序

选择排序( Selection sort)是一种简单直观的排序算法。它的工作原理是每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。

   选择排序算法通过选择和交换来实现排序,其排序流程如下:

(1)首先从原始数组中选择最小的1个数据,将其和位于第1个位置的数据交换。
(2)接着从剩下的n-1个数据中选择次小的1个元素,将其和第2个位置的数据交换
(3)然后,这样不断重复,直到最后两个数据完成交换。最后,便完成了对原始数组的从小到大的排序。
假如给定初始数据:(118,101,105,127,112)

一次排序:101,118,105,127,112

二次排序:101,105,118,127,112

三次排序:101,105,112,127,118

四次排序:101,105,112,118,127

(绿色为交换的数据)

每一趟在n-i+1(i=1,2,...,n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录。具体来说,假设长度为n的数组arr,要按照从小到大排序,那么先从n个数字中找到最小值min1,如果最小值min1的位置不在数组的最左端(也就是min1不等于arr[0]),则将最小值min1和arr[0]交换,接着在剩下的n-1个数字中找到最小值min2,如果最小值min2不等于arr[1],则交换这两个数字,依次类推,直到数组arr有序排列。算法的时间复杂度为O(n^2)。

void Select_Sort(int* arr, int n)   //arr为数据数组,n为数组长度
{
	for (int i = 0; i < n-1; i++) {
		int min = i;
		for (int j = i; j < n; j++) {
			if (arr[min] > arr[j]) {
				min = j;
			}
		}
		if (min != i) {
			swap(arr[i], arr[min]);
		}
	}
}

四、堆排序

如果不了解可以去看我写过关于堆的博客,里面有详细介绍:
http://t.csdnimg.cn/VGbOO

void AdjustDown(int* a, int n, int parent)
{
	// 先假设左孩子小
	int child = parent * 2 + 1;

	while (child < n)  // child >= n说明孩子不存在,调整到叶子了
	{
		// 找出小的那个孩子
		if (child + 1 < n && a[child + 1] > a[child])
		{
			++child;
		}

		if (a[child] > a[parent])
		{
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

void HeapSort(int* a, int n)
{
	// 向下调整建堆 O(N)
	for (int i = (n - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(a, n, i);
	}

	// O(N*logN)
	int end = n - 1;
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		AdjustDown(a, end, 0);
		--end;
	}
}

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

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

相关文章

智能单款计划助力品牌利润增长

零售品牌若要在激烈的市场竞争中胜出&#xff0c;季中单款的管理无疑是商品生命周期管理的核心环节之一。而单款计划的制定&#xff0c;首先依赖于对爆款、平销及滞销产品的敏锐洞察。一个利润现象不得不引起我们的关注&#xff1a;爆款产品的销售&#xff0c;往往成为拉动品牌…

「实用推荐」如何为桌面 移动跨平台应用选择UI框架/APP架构?

DevExpress .NET MAUI UI组件库提供了用于Android和iOS移动开发的高性能UI组件&#xff0c;该库包括数据网格、图表、日程、数据编辑器、CollectionView和选项卡组件。 获取DevExpress .NET MAUI最新正式版下载(Q技术交流&#xff1a;532598169&#xff09; “一次编写&#…

03 FreeRTOS 同步互斥与通信

1、同步与互斥 一句话理解同步与互斥&#xff1a;我等你用完厕所&#xff0c;我再用厕所。 什么叫同步&#xff1f;就是&#xff1a;哎哎哎&#xff0c;我正在用厕所&#xff0c;你等会。 什么叫互斥&#xff1f;就是&#xff1a;哎哎哎&#xff0c;我正在用厕所&#xff0c;你…

笔试强训week6

day1 Q1 难度⭐⭐ 小红的口罩_牛客小白月赛41 (nowcoder.com) 题目&#xff1a; 疫情来了&#xff0c;小红网购了 n 个口罩。 众所周知&#xff0c;戴口罩是很不舒服的。小红每个口罩戴一天的初始不舒适度为 ai​。 小红有时候会将口罩重复使用&#xff08;注&#xff1a;…

什么是死锁,如何解决?

一、问题解析 死锁是指两个或两个以上的进程&#xff08;或线程&#xff09;在执行过程中&#xff0c;由于竞争资源或者由于彼此通信而造成的一种阻塞的现象&#xff0c;若无外力作用&#xff0c;它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁&#xff0c;这些…

网上有哪些正规的兼职副业赚钱平台?分享10类正规的网上兼职赚钱平台,让你在家也能赚钱~

在如今的快节奏社会中&#xff0c;越来越多的人开始寻求兼职副业来增加收入。而随着互联网的普及&#xff0c;网上赚钱平台成为了许多人选择的方式之一。然而&#xff0c;面对众多的网上赚钱平台&#xff0c;我们要如何辨别哪些是正规可靠的呢&#xff1f;在本文中&#xff0c;…

解读:Mint Blockchain 最新路线图,释放 NFT 生态重磅发展计划

作者&#xff1a;Mint Ecosystem 关于 Mint Blockchain&#xff1a;Mint Blockchain 是一个以太坊原生 L2 网络&#xff0c;核心是发展 NFT 生态和产业&#xff0c;促进 NFT 领域的 Mass Adoption 产生。MintCore 团队致力于将 Mint Blockchain 打造成一个围绕服务 NFT 资产的…

6万转高速主轴电机哪个品牌好?

近年来&#xff0c;随着全球科技的迅猛发展&#xff0c;各个工业领域对高精密零件加工的需求日益旺盛&#xff0c;特别是在医疗、航天航空、通讯技术等领域&#xff0c;对工件的精密性要求达到了前所未有的高度。在这样的背景下&#xff0c;高转速&#xff0c;高精密的高速电主…

yolo 算法 易主

标题&#xff1a;YOLOv10: Real-Time End-to-End Object Detection 论文&#xff1a;https://arxiv.org/pdf/2405.14458ethttps%3A//arxiv.org/pdf/2405.14458.zhihu.com/?targethttps%3A//arxiv.org/pdf/2405.14458 源码&#xff1a;https://github.com/THU-MIG/yolov10 分析…

哈夫曼树,哈夫曼编码和线索二叉树

前言 在数据压缩中,如电脑中的压缩软件,哈夫曼编码应用比较广泛,因此被称作最优二叉树。下面时哈夫曼树的一些定义。 哈夫曼树 定义 代码 下面时哈夫曼树的初始化和创建: #include "stdio.h"#define MAXSIZE 5 typedef struct {int weigth;int parent, lchi…

SSRS中使用QRCoder生成二维码

步骤 1.下载QRCoder.dll 下载地址&#xff1a;https://download.csdn.net/download/wjl7126180/89369398 2.使用gacutil.exe安装QRCoder.dll到GAC(Global Assembly Cache) gacutil.exe是全局程序集缓存工具&#xff0c;需要安装.NET Framework才会存在&#xff0c;如果没有…

质量人,你还在等什么?快来六西格玛培训公司充电吧!——张驰咨询

在竞争激烈的商业环境中&#xff0c;质量成为了企业生存和发展的关键。而六西格玛&#xff0c;作为一种全球公认的质量管理方法论&#xff0c;正在成为越来越多企业追求品质革命的重要工具。而六西格玛培训公司&#xff0c;则成为了这场品质革命中&#xff0c;质量人不可或缺的…

SSH秘钥对简化github项目管理(外加Tortoise配置)

文章目录 使用SSH秘钥对简化github项目管理为什么要用密钥对&#xff1f;如何使用SSH方式克隆版本库呢&#xff1f;补充&#xff1a;使用TortoiseGit&#xff08;小乌龟&#xff09;快速访问github远程仓库&#xff01;结尾&#xff1a;喜欢的小伙伴可以点点关注赞哦 使用SSH秘…

四大策略,五大优势!麒麟信安云助力用户实现VMware替换无忧

2023 年 12 ⽉ 11 ⽇&#xff0c;VMware 正式官宣“所有 VMware by Broadcom 解决⽅案向订阅许可证的过渡&#xff0c;并停⽌销售永久许可证、永久产品的⽀持和订阅&#xff08;SnS&#xff09;续订以及混合购买计划/订阅购买计划积分&#xff08;HPP/SPP&#xff09;”。 202…

根据一棵树的前序遍历与中序遍历构造二叉树(C++)

文章目录 1. 题目描述2. 题目解析 题目来源&#xff1a; 力扣…根据一棵树的前序遍历与中序遍历构造二叉树 1. 题目描述 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二…

python清洗苹果产量数据:从字符串到整型的转化

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、使用普通方法清洗数据 1. 创建字典并遍历 2. 示例代码 3. 结果展示 三、使…

教你网站如何免费实现https

想要实现https访问最简单有效的的方法就是安装SSL证书。只要证书正常安装上以后&#xff0c;浏览器就不会出现网站不安全提示或者访问被拦截的情况。下面我来教大家怎么去获取免费的SSL证书&#xff0c;又如何安装证书实现https访问。 一、选择免费SSL证书提供商 有多家机构提…

计算机SCI期刊,中科院2区,IF=5+,收稿范围广泛!

一、期刊名称 CAAI Transactions on Intelligence Technology 二、期刊简介概况 期刊类型&#xff1a;SCI 学科领域&#xff1a;计算机科学 影响因子&#xff1a;5.1 中科院分区&#xff1a;2区 出版方式&#xff1a;开放出版 版面费&#xff1a;$2600 三、期刊简介 期…

在今日头条上写文章:ChatGPT完整使用教程

了解如何充分运用ChatGPT进行创作 简介 在今日头条上发布文章变得越来越方便。本文旨在详细解析如何运用ChatGPT来创作文章&#xff0c;并提供全方位的使用指南及常见问题的答疑。 第一步&#xff1a;基础准备 确保你已注册今日头条账号。 登录ChatGPT并与你的今日头条账号进…

质量源于设计QbD培训的内容有哪些?

质量源于设计QbD培训的内容丰富而深入&#xff0c;旨在帮助企业深入理解并应用QbD理念&#xff0c;提升产品质量和客户满意度。以下是质量源于设计QbD培训的主要内容&#xff1a; 首先&#xff0c;培训将详细介绍QbD的基本概念、核心内容和实施流程。QbD是一种集成的方法&#…