【数据结构】排序详解(希尔排序,快速排序,堆排序,插入排序,选择排序,冒泡排序)

news2024/11/25 1:02:46

目录

0. 前情提醒:

1. 插入排序

1.1 基本思想:

1.2 直接插入排序

 实现步骤:

 动图演示:

 特性总结:

 代码实现:

1.3 希尔排序(缩小增量排序)

基本思想:

步骤演示:

特性总结:

代码实现:

2. 交换排序

2.1 基本思想:

2.2 冒泡排序

特性总结:

代码实现:

2.3 快速排序

3.选择排序

3.1 基本思想:

3.2 直接选择排序

步骤思路:

动图演示: 

特性总结:

代码实现:

3.3 堆排序

代码实现:


0. 前情提醒:

下面的所有代码实现均为升序

1. 插入排序

1.1 基本思想:

把待排序的记录按其关键码值的大小逐个插入到一个已经排序好的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。

1.2 直接插入排序
 实现步骤:

当插入第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. 4.稳定性:稳定
 代码实现:
void InsertSort(int* a, int n) {
	for (int i = 0; i < n; i++) {
		int m = a[i];
		int end = i;
		while (end > 0 && a[end - 1] > m) {
			a[end] = a[end - 1];
			end--;
		}
		a[end] = m;
	}
}
1.3 希尔排序(缩小增量排序)
基本思想:

先选定一个整数,把待排序的文件中所有(n个)记录分成(n/gap)个组,所有距离为gap的记录分在同一个组,并对每个组内的记录进行排序。然后去gap=gap/2,重复上述分组和排序的工作。当到达gap=1时,所有记录在统一组内排好序(gap=1时就是直接插入排序,gap>1时属于预排序)。

步骤演示:

特性总结:
  1. 希尔排序是对直接插入排序的优化
  2. 当gap>1时都是预排序,目的是让数组更接近有序。当gap==1时,数组已经接近有序,这样排序就会很快。这样整体而言,可以达到优化的效果
  3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在不同书上给出的希尔排序的时间复杂度都不一样
代码实现:
void ShellSort(int* a, int n) {
	int gap = n;
	while (gap > 1) {
		gap = gap / 3 + 1;
		for (int i = 0; i < n; i++) {
			int m = a[i];
			int end = i;
			while (end > 0 && a[end - gap] > m) {
				a[end] = a[end - gap];
				end -= gap;
			}
			a[end] = m;
		}
	}
}

2. 交换排序

2.1 基本思想:

所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向前部移动

2.2 冒泡排序

左边大于右边交换,一趟排下来最大的在右边

特性总结:
  1. 冒泡排序是一种非常容易理解的排序
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1)
  4. 稳定性:稳定
代码实现:
void BubbleSort(int* a, int n) {
	for (int i = 0; i < n; i++) {
		int k = 1;
		for (int j = 0; j < n-i-1; j++) {
			if (a[j] > a[j + 1]) {
				k = 0;
				int x = a[j];
				a[j] = a[j + 1];
				a[j + 1] = x;
			}
		}
		if (k) {
			break;
		}
	}
}
2.3 快速排序

快速排序较为复杂,想了解请点击-----》快速排序

3.选择排序

3.1 基本思想:

每一次从待排序的数据元素中选出一个最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完

3.2 直接选择排序
步骤思路:
  • 在元素array[i]--array[n-1]中选择关键码最小(或最大)的数据元素
  • 若它不是这组元素中最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换
  • 在剩余的array[i]--array[n-2](array[i+1]--array[n-1])集合中,重复上述步骤,直到集合剩余1个元素
动图演示: 

特性总结:
  1. 思路很好理解,但效率不好,实际很少应用,主要具有教学意义
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1)
  4. 稳定性:不稳定
代码实现:
void SelectSort(int* a, int n) {
	for (int i = 0; i < n; i++) {
		int min = n - 1;
		for (int j = i; j < n; j++) {
			if (a[min] > a[j]) {
				min = j;
			}
		}
		swap(&a[min], &a[i]);
	}
}
3.3 堆排序

堆排序(HeapSort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据,利用堆中某个节点的值总是不大于或不小于其父节点的值的特性。注意:升序建大堆,降序建小堆

代码实现:
void AdjustDwon(int* a, int n, int root) {
	int i = 2 * root + 1;
	if (i < n - 1 && a[i] < a[i + 1]) {
		i++;
	}
	if (i < n && a[root] < a[i]) {
		swap(&a[root], &a[i]);
		AdjustDwon(a, n, i);
	}
}
void HeapSort(int* a, int n) {
//建堆
	for (int i = (n - 1 - 1) / 2; i >= 0; i--) {
		AdjustDwon(a, n, i);
	}
	while (n>1) {
		swap(&a[0], &a[n-1]);
		n--;
		AdjustDwon(a, n, 0);
	}
}

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

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

相关文章

谷歌上架,个人号比企业号好上?“14+20”封测如何解决,你知道了吗

在Google Play上架应用&#xff0c;对开发者而言&#xff0c;既是挑战也是机遇。随着谷歌政策的不断更新&#xff0c;特别是要求2023年11月13日后注册的个人开发者账号在发布正式版应用前&#xff0c;必须经过20人连续14天的封闭测试。 这一政策的改变使得许多开发者开始考虑使…

适合小白入门的AI扩图(创成式填充)工具

近期&#xff0c;发现许多人对AI扩图工具的需求比较大&#xff0c;为了满足大家的需求&#xff0c;本期天祺为大家整理了一些好用的AI扩图工具&#xff0c;各个设配的扩图工具都有介绍哦&#xff0c;电脑&#xff0c;手机端都能用&#xff0c;大家可以根据自己的喜好和需求进行…

Linux程序开发(十):文件分类器趣味设计

Tips&#xff1a;"分享是快乐的源泉&#x1f4a7;&#xff0c;在我的博客里&#xff0c;不仅有知识的海洋&#x1f30a;&#xff0c;还有满满的正能量加持&#x1f4aa;&#xff0c;快来和我一起分享这份快乐吧&#x1f60a;&#xff01; 喜欢我的博客的话&#xff0c;记得…

搜索插入位置 ---- 二分查找

题目链接 题目: 分析: 因为数排序数组, 所以具有"二段性", 可以使用二分查找题目中, 我们如果找到目标值 , 则返回下标, 如果没找到目标值, 应该返回的是>target的第一个位置, 所以应该将数组分成< target 和 > target当<target时, 应该移动left, left…

Marin说PCB之POC电路layout设计仿真案例---03

今天中午午休我刚要打开手机的准备刷抖音看无忧传媒的学生们的“学习资料”的时候&#xff0c;看到CSDN -APP上有提醒&#xff0c;一看原来是一位道友发的一个问题&#xff1a; 本来小编最近由于刚刚从国外回来&#xff0c;手上的项目都已经结束了&#xff0c;这周开始学习仿真…

Xcode=> 安装 simulator

XCode xcode中下载 simulator 点击加号➕&#xff0c;选择对应的版本&#xff0c;即可下载 下载完成&#xff1a; 其他下载办法 因为使用上述下载&#xff0c;会经常性的出现断开&#xff0c;再次下载又是从头开始&#xff0c;太费时费力。下面使用下载地址&#xff0c;然后用…

软考中级-软件设计师-真题详解【2023年上半年】

2023上半年真题记忆点详解 本片不涉及解题法&#xff0c;只整理记忆背诵点&#xff0c;记住即可拿分。 上午题部分&#xff1a; 片内总线&#xff1a;用于芯片内部各主要部件连接&#xff1b; 系统总线&#xff1a;用于CPU、主存、外设见的数据传输&#xff1b; 通讯总线&…

百度信息流 - 成本保障未生效?

今天创建百度信息流单元时&#xff0c;发现一个细节&#xff0c;创建好后&#xff0c;成本保障未生效&#xff08;“保”字没有出现&#xff09; 过了一会&#xff0c;再进来看&#xff0c;成本保障生效了。 分析原因 &#xff1a; 展现为 1 &#xff0c;也就是说&#xff0c;一…

建筑施工突发事故应急处置vr安全培训平台

在不断发展的时代背景下&#xff0c;掌握必要的应急安全知识已成为我们生活中不可或缺的一部分。由央企携手我们华锐推出的3D线上应急宣教虚拟体验馆&#xff0c;标志着民众应急安全教育的全新里程碑&#xff0c;不仅突破了传统学习模式的局限&#xff0c;还让每个人都能在灵活…

GpuMall智算云:Ubuntu 实例桌面版

基于 ubuntu18.04 安装的桌面版本&#xff0c;桌面使用 xfce4 &#xff0c;集成了 Pytorch2.3.0、cuda11.8、Python3.10、VNC、noVNC、VSCode-Server。 在 镜像市场 选择xfce4-desktop镜像&#xff0c;然后进行创建实例 GpuMall智算云 | 省钱、好用、弹性。租GPU就上GpuMall…

这八个步骤,有效进行防错管理

导读 在产品实际的生产过程中&#xff0c;因零件相似而错装、因零件又小又多而漏装等现象时有发生&#xff0c;需要防止或尽可能避免错误发生。 试想&#xff0c;一个操作人员每天进行同样的装配工作上百次千次甚至上万次&#xff0c;如果产品设计和过程设计开发不能防止提前预…

vue.js状态管理和服务端渲染

状态管理 vuejs状态管理的几种方式 组件内管理状态&#xff1a;通过data&#xff0c;computed等属性管理组件内部状态 父子组件通信&#xff1a;通过props和自定义事件实现父子组件状态的通信和传递 事件总线eventBus&#xff1a;通过new Vue()实例&#xff0c;实现跨组件通…

Pytorch入门(7)—— 梯度累加(Gradient Accumulation)

1. 梯度累加 在训练大模型时&#xff0c;batch_size 最大值往往受限于显存容量上限&#xff0c;当模型非常大时&#xff0c;这个上限可能小到不可接受。梯度累加&#xff08;Gradient Accumulation&#xff09;是一个解决该问题的 trick梯度累加的思想很简单&#xff0c;就是时…

第12周作业--HLS入门

目录 一、HLS入门 二、HLS入门程序编程 创建项目 1、点击Vivado HLS 中的Create New Project 2、设置项目名 3、加入文件 4、仿真 3、综合 一、HLS入门 1. HLS是什么&#xff1f;与VHDL/Verilog编程技术有什么关系? HLS&#xff08;High-Level Synthesis&#xff0c…

自动化重置数据库功能的探索与实践

1、简介 在现代软件开发中&#xff0c;尤其是涉及到数据驱动的应用程序时&#xff0c;开发和测试环境中数据库的管理是至关重要的一环。为了确保开发和测试环境中的数据库始终处于一致的状态&#xff0c;自动化重置数据库成为了一种常见的实践。本文旨在介绍如何通过Shell脚本…

打印9*9乘法表(递归或压缩矩阵)python

打印9*9表def print_multiplication_table(row, col):if row > 10:return # 递归结束条件if col row:print() # 换行print_multiplication_table(row 1, 1) # 递归调用下一行else:print(f"{row-1} * {col} {(row-1) * col}\t", end"") # 打印乘法…

小程序properties默认值定义及父子组件的传值

因经常写vue&#xff0c;很久没写小程序&#xff0c;容易串频道&#xff0c;现记录一下小程序的组件用法、监听传入值及父子传值方式 首先小程序中传值是没有&#xff1a;(冒号)的&#xff0c;其次properties中定义默认值不需要写default 1.自定义组件中&#xff0c;首先json…

TransFormer学习之基础知识:STN、SENet、CBAM、Self-Attention

1.空间注意力机制STN 参考链接&#xff1a;STN(Spatial Transformer Networks) 参考链接&#xff1a;通俗易懂的Spatial Transformer Networks(STN) 核心动机&#xff1a; 在空间中捕获重要区域特征(如图像中的数字)&#xff0c;将核心区域进行放大居中&#xff0c;使得结果更…

2461. 长度为 K 子数组中的最大和(c++)

给你一个整数数组 nums 和一个整数 k 。请你从 nums 中满足下述条件的全部子数组中找出最大子数组和&#xff1a; 子数组的长度是 k&#xff0c;且子数组中的所有元素 各不相同 。 返回满足题面要求的最大子数组和。如果不存在子数组满足这些条件&#xff0c;返回 0 。 子数…

第七节 ConfigurationClassParser 源码分析

tips&#xff1a; ConfigurationClassParser 是 Springframework 中的重要类。 本章主要是源码理解&#xff0c;有难度和深度&#xff0c;也枯燥乏味&#xff0c;可以根据实际情况选择阅读。 位置&#xff1a;org.springframework.context.annotation.ConfigurationClassPars…