数据结构(初阶)(八)----排序

排序

概念

排序:所谓排序,就是使⼀串记录,按照其中的某个或某些关键字的⼤⼩,递增或递减的排列起来的 操作。

比较排序

image-20250219165832319

插入排序

直接插入排序

直接插⼊排序是⼀种简单的插⼊排序法,其基本思想是:把待排序的记录按其关键码值的⼤⼩逐个插⼊到⼀个已经排好序的有序序列中,直到所有的记录插⼊完为⽌,得到⼀个新的有序序列 。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

希尔排序

希尔排序法⼜称缩⼩增量法。希尔排序法的基本思想是:先选定⼀个整数(通常是gap = n/3+1),把待排序⽂件所有记录分成各组,所有的距离相等的记录分在同⼀组内,并对每⼀组内的记录进⾏排序,然后gap=gap/3+1得到下⼀个整数,再将数组分成各组,进⾏插⼊排序,当gap=1时,就相当于直接插⼊排序。

它是在直接插⼊排序算法的基础上进⾏改进⽽来的,综合来说它的效率肯定是要⾼于直接插⼊排序算法的。

1,gap > 1,预排序

2,gap = 1,直接插入排序(时间复杂度接近O(n))

希尔排序的时间复杂度估算:

外层循环:

外层循环的时间复杂度可以直接给出为: O(log2 n) 或者 O(log3 n) ,即 O(log n)

内层循环:

选择排序

选择排序的基本思想:

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

直接选择排序

直接选择排序的特性总结:

1,直接选择排序思考⾮常好理解,但是效率不是很好。实际中很少使⽤

2, 时间复杂度: O(N2 )

3,空间复杂度: O(1)

堆排序

交换排序

冒泡排序

快速排序

快速排序是Hoare于1962年提出的⼀种⼆叉树结构的交换排序⽅法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两⼦序列,左⼦序列中所有元素均⼩于基准值,右⼦序列中所有元素均⼤于基准值,然后最左右⼦序列重复该过程,直到所有元素都排列在相应位置上为⽌。

//快速排序
void QuickSort(int* arr, int left, int right)
{
	if (left >= right)
		return;
	//确定基准值
	int keyi = _QuickSort(arr, left, right);
	QuickSort(arr, left, keyi-1);
	QuickSort(arr, keyi+1,right);
}

如何将基准值放到相应的位置?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最差情况是n^2

快速排序特性总结:

1,时间复杂度: O(nlogn)

2,空间复杂度: O(logn)

1, hoare版本

算法思路 :

1,创建左右指针,确定基准值

2,从右向左找出⽐基准值⼩的数据,从左向右找出⽐基准值⼤的数据,左右指针数据交换,进⼊下次循环

//确定基准值
int _QuickSort(int* arr, int left, int right)
{
	int keyi = left;
	++left;

	while (left <= right)
	{
		//右边找小
		while (left <= right && arr[right] > arr[keyi])
		{
			--right;
		}
		//左边找大
		while (left <= right && arr[left] < arr[keyi])
		{
			++left;
		}
		if (left <= right)
		{
			swap(&arr[left++], &arr[right--]);
		}
	}

	swap(&arr[keyi], &arr[right]);
	return right;
}
2,挖坑法

创建左右指针。⾸先从右向左找出⽐基准⼩的数据,找到后⽴即放⼊左边坑中,当前位置变为新

的"坑",然后从左向右找出⽐基准⼤的数据,找到后⽴即放⼊右边坑中,当前位置变为新的"坑",结束循环后将最开始存储的分界值放⼊当前的"坑"中,返回当前"坑"下标(即分界值下标)

//挖坑法
int _QuickSort2(int* arr, int left, int right)
{
	int key = arr[left];
	int hole = left;

	while (left < right)
	{
		//右边找小
		while (left < right && arr[right] >= key)
		{
			--right;
		}
		arr[hole] = arr[right];
		hole = right;
		//左边找大
		while (left < right && arr[left] <= key)
		{
			++left;
		}
		arr[hole] = arr[left];
		hole = left;
	}
	arr[hole] = key;
	return hole;
}
3,双指针法(lomuto前后指针 )

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

//双指针法(lomuto前后指针 )
int _QuickSort3(int* arr, int left, int right)
{
	int key = left;
	int  prev = left;
	int cur = left + 1;

	while (cur <= right)
	{
		if (arr[cur] < arr[key] && ++prev != cur)
		{
			swap(&arr[prev], &arr[cur]);
		}
		cur++;
	}
	swap(&arr[key], &arr[prev]);
	return prev;
}
非递归版本的快速排序

归并排序

排序算法思想:

归并排序(MERGE-SORT)是建⽴在归并操作上的⼀种有效的排序算法,该算法是采⽤分治法(Divide

and Conquer)的⼀个⾮常典型的应⽤。将已有序的⼦序列合并,得到完全有序的序列;即先使每个

⼦序列有序,再使⼦序列段间有序。若将两个有序表合并成⼀个有序表,称为⼆路归并。

void _MergeSort(int* arr, int left, int right, int* tmp)
{
	if (left >= right)
	{
		return;
	}
	int mid = (left + right) / 2;
	_MergeSort(arr, left, mid, tmp);
	_MergeSort(arr, mid + 1, right, tmp);

	int begin1 = left, end1 = mid;
	int begin2 = mid + 1, end2 = right;
	int index = begin1;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (arr[begin1] < arr[begin2])
		{
			tmp[index++] = arr[begin1++];
		}
		else
		{
			tmp[index++] = arr[begin2++];
		}
	}
	while (begin1 <= end1)
	{
		tmp[index++] = arr[begin1++];
	}
	while (begin2 <= end2)
	{
		tmp[index++] = arr[begin2++];
	}
	//拷贝,可以使用memcopy,也可以使用循环
	for (int i = left; i <= right; i++)
	{
		arr[i] = tmp[i];
	}
}

//归并排序
void MergeSort(int* arr, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		perror("malloc fail");
		exit(1);
	}
	_MergeSort(arr, 0, n - 1, tmp);
	free(tmp);
	tmp = NULL;
}

非比较排序

计数排序

计数排序⼜称为鸽巢原理,是对哈希直接定址法的变形应⽤。 操作步骤:

1,统计相同元素出现次数

2,根据统计的结果将序列回收到原来的序列中

//非比较排序
//计数排序
void CountSort(int* arr, int n)
{
	int min = arr[0], max = arr[0];
	for (int i = 1; i < n; i++)
	{
		if (arr[i] < min)
		{
			min = arr[i];
		}
		if (arr[i] > max)
		{
			max = arr[i];
		}
	}
	
	int range = max - min + 1;
	int* count = (int*)malloc(sizeof(int)*range);
	if (count == NULL)
	{
		perror("malloc fail");
		exit(1);
	}
	memset(count, 0, sizeof(int) * range);

	for (int i = 0; i < n; i++)
	{
		count[arr[i] - min]++;
	}

	int j = 0;
	for (int i = 0; i < range; i++)
	{
		while (count[i]--)
		{
			arr[j++] = i + min;
		}
	}
}

稳定性

稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的

相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,⽽在排序后的序列中,r[i]仍在r[j]之

前,则称这种排序算法是稳定的;否则称为不稳定的。

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

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

相关文章

计算机毕业设计SpringBoot+Vue.js基于JAVA语言的在线考试与学习交流网页平台(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

聊一聊 IM 如何优化数据库

IM 系列 im doc 实时通讯文档仓库 聊一聊 IM 是什么&#xff1f; IM 即时通讯系统概览 聊一聊 IM 要如何设计&#xff1f; 聊一聊 IM 要如何设计功能模块&#xff1f; 聊一聊 IM 要如何进行架构设计&#xff1f; 聊一聊 IM 要如何进行技术选型&#xff1f; 聊一聊 IM 要…

人工智能AI在汽车设计领域的应用探索

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 简单&#xff0c;单纯&#xff0c;喜欢独处&#xff0c;独来独往&#xff0c;不易合同频过着接地气的生活…

DeepSeek-R1 大模型实战:腾讯云 HAI 平台 3 分钟极速部署指南

引言&#xff1a;为什么选择 DeepSeek-R1&#xff1f; 近期&#xff0c;国产大模型 DeepSeek-R1 因其低成本、高性能的特点在全球 AI 领域引发热议。根据 Sensor Tower 数据&#xff0c;其发布仅 18 天便斩获 1600 万次下载量&#xff0c;远超 ChatGPT 同期表现。而腾讯云推出…

[SWPUCTF 2022 新生赛]1z_unserialize

题目描述&#xff1a;是很简单的反序列化噢 代码审计看注释 <?phpclass lyh{ //定义一个类为lyhpublic $url NSSCTF.com;//公共属性&#xff0c;初始值为NSSCTF.compublic $lt; //公共属性&#xff0c;没有初始值public $lly; //公共属性&…

三支一扶入职体检不合格项目全解析

“三支一扶” 计划为高校毕业生提供了到基层服务的宝贵机会&#xff0c;通过层层选拔后&#xff0c;入职体检也是其中关键的一环。了解哪些项目可能导致体检不合格&#xff0c;能让大家提前做好准备&#xff0c;避免在这一步出现意外。接下来&#xff0c;就为大家详细介绍三支一…

专题一四数之和

1.题目 题目分析&#xff1a; 给一个数组&#xff0c;在里面找到四个数字&#xff0c;满足四个数字之和等于给的特定值&#xff0c;四数之和可以拆分成三数之和&#xff0c;再继续拆分成二数之和&#xff0c;由简化繁。 2.算法原理 通过排序加双指针 1.依次固定一个数 2.在…

如何在docker中的mysql容器内执行命令与执行SQL文件

通过 docker ps -a 查询当前运行的容器&#xff0c;找到想执行命令的容器名称。 docker ps -a若想执行sql文件&#xff0c;则将sql文件放入当前文件夹下后将项目内的 SQL 文件拷贝到 mysql 容器内部的 root下。 sudo docker cp /root/enterprise.sql mysql:/root/然后进入 my…

Linux线程同步与互斥应用/生产者消费者模型

一&#xff0c;理论讲解 我们拿工厂&#xff0c;超市和消费者直接的关系来做讲解&#xff0c;首先人去超市买东西的过程就不用多说&#xff0c;但是超市本身是不能生产商品的&#xff0c;他们需要从各个不同的工厂进货商品&#xff0c;然后再给消费者买&#xff0c;以计算机的…

基于YOLO11深度学习的遥感视角农田检测与分割系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分割、人工智能

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

RabbitMQ面试题及原理

RabbitMQ使用场景&#xff1a; 异步发送&#xff08;验证码、短信、邮件…&#xff09;MYSQL和Redis, ES之间的数据同步分布式事务削峰填谷 1. 消息可靠性&#xff08;不丢失&#xff09; 消息丢失场景&#xff1a; RabbitMQ-如何保证消息不丟失&#xff1f; 开启生产者确…

Python每日一练:学习指南进行汇总

Python&#xff0c;一种“优雅”、“明确”、“简单”的编程语言&#xff0c;凭借其低学习曲线、强大的开源生态系统、卓越的平台可移植性以及面向对象和函数式编程的支持&#xff0c;成为了众多开发者首选。 01 Python 应用领域和就业形势分析 Python&#xff0c;一种“优雅…

商米科技前端工程师(base上海)内推

1.根据原型或高保真设计&#xff0c;开发web、H5、小程序等类型的前端应用&#xff1b; 2.在指导下&#xff0c;高质量完成功能模块的开发&#xff0c;并负责各功能模块接口设计工作&#xff1b; 3.负责产品及相关支撑系统的开发及维护工作&#xff0c;不断的优化升级&#x…

八. Spring Boot2 整合连接 Redis(超详细剖析)

八. Spring Boot2 整合连接 Redis(超详细剖析) 文章目录 八. Spring Boot2 整合连接 Redis(超详细剖析)2. 注意事项和细节3. 最后&#xff1a; 在 springboot 中 , 整合 redis 可以通过 RedisTemplate 完成对 redis 的操作, 包括设置数据/获取数据 比如添加和读取数据 具体…

【漫话机器学习系列】113.逻辑回归(Logistic Regression) VS 线性回归(Linear Regression)

逻辑回归 vs 线性回归&#xff1a;详解对比 在机器学习和统计学中&#xff0c;逻辑回归&#xff08;Logistic Regression&#xff09; 和 线性回归&#xff08;Linear Regression&#xff09; 都是非常常见的模型。尽管它们的数学表达式有一定的相似性&#xff0c;但它们的应用…

构建智能 SQL 查询代理agent,把整个查询过程模块化,既能自动判断使用哪些表,又能自动生成 SQL 语句,最终返回查询结果

示例代码&#xff1a; import os import getpass from dotenv import load_dotenv from pyprojroot import here from typing import List from pprint import pprint from pydantic import BaseModel from langchain_core.tools import tool from langchain_core.runnables i…

fastapi中的patch请求

目录 示例测试使用 curl 访问&#xff1a;使用 requests 访问&#xff1a;预期返回&#xff1a; 浏览器访问 示例 下面是一个使用 app.patch("") 的 FastAPI 示例&#xff0c;该示例实现了一个简单的用户信息更新 API。我们使用 pydantic 定义数据模型&#xff0c;并…

【文献阅读】Collective Decision for Open Set Recognition

基本信息 文献名称&#xff1a;Collective Decision for Open Set Recognition 出版期刊&#xff1a;IEEE TRANSACTIONS ON KNOWLEDGE AND DATA ENGINEERING 发表日期&#xff1a;04 March 2020 作者&#xff1a;Chuanxing Geng and Songcan Chen 摘要 在开集识别&#xff0…

Hadoop之02:MR-图解

1、不是所有的MR都适合combine 1.1、map端统计出了不同班级的每个学生的年龄 如&#xff1a;(class1, 14)表示class1班的一个学生的年龄是14岁。 第一个map任务&#xff1a; class1 14 class1 15 class1 16 class2 10第二个map任务&#xff1a; class1 16 class2 10 class…

代码随想录Day23 | 39.组合总和、40.组合总和II、131.分割回文串

39.组合总和 自己写的代码&#xff1a; class Solution { public:vector<int> path;vector<vector<int>> res;int sum0;void backtracking(vector<int>& candidates,int target,int startIndex){if(sum>target) return;if(sumtarget){res.pus…