排序(快速排序 归并排序)

news2024/9/22 7:28:16

目录

一、快速排序

思路

动画演示

模板

注意点

二、归并排序

思路

动画演示

模板

注意点

三、习题

1.第k个数

2.数组中的逆序对*


一、快速排序

时间复杂度:

平均情况O(nlog2n)

最坏情况O(n^2)

思路

1. 确定分界点x (可取为q[l]、q[r]或 q[(l + r) / 2])

【x被称为支点(pivot),也称为枢轴元素。】

2. 划分区间 ( 将区间[l, r]划分为 <= x 和 >= x )【重点

3. 利用递归把小于基准值元素的子数列和大于基准值元素的子数列进行排序

动画演示

模板

void quick_sort(vector<int>& q, int l, int r)
{
	if (l >= r) return;
	int x = q[(r + l) >> 1], i = l - 1, j = r + 1;
	while (i < j)
	{
		do i++; while (q[i] < x);
		do j--; while (q[j] > x);
		if (i < j) std::swap(q[i], q[j]);
	}
	quick_sort(q, l, j);
	quick_sort(q, j + 1, r);
}

注意点

【注意边界问题】

取左端点或右端点作为支点元素的方法比较简单,但是在某些情况下可能会导致快速排序算法出现最坏情况。

例如待排序数组已经有序或者接近有序的情况下。在这种情况下,取左端点或右端点作为支点元素会导致分割出来的左右两个子数组极度不平衡,导致算法效率变得极低。

取中间点作为支点元素的方法可以避免快速排序算法出现最坏情况,但是需要额外的计算来确定中间点的位置,可能会导致效率降低。因此,一般来说,随机选择法或三数取中法更常用,它们都可以避免最坏情况的发生,同时具有较高的效率和良好的性能。

切忌将 q[i] < x 改为 q[i] <= x 或是将 q[j] > x 改为 q[j] >= x ,会导致满足条件的数组下,指针无限移动,无限循环。

当支点选择q[l]时,递归填入区间必须为[l, j]和[j + 1, r];当支点选择q[r]时,递归递归填入区间必须为[l, i]和[i + 1, r],否则会触发边界问题。

二、归并排序

时间复杂度:O(nlog2n)

思路

1. 确定分界点

2. 递归排序

3. 归并(合二为一)【重点

动画演示

在这里插入图片描述

模板

const int N = 1000;
vector<int> tmp(N);
void merge_sort(vector<int>& q, int l, int r)
{
	if (l >= r) return;
	int mid = (l + r) >> 1;
	merge_sort(q, l, mid);
	merge_sort(q, mid + 1, r);
	int i = l, j = mid + 1, k = 0;
	while (i <= mid && j <= r)
		if (q[i] <= q[j]) tmp[k++] = q[i++];
		else tmp[k++] = q[j++];
	while (i <= mid) tmp[k++] = q[i++];
	while (j <= r) tmp[k++] = q[j++];
	
	for (i = l, j = 0; i <= r; ++i, ++j) q[i] = tmp[j];
}

注意点

  1. 确定归并排序的边界条件:在实现归并排序时,需要确定递归终止的边界条件,一般是当待排序数组的大小小于等于1时,直接返回即可。

  2. 数组下标越界问题:在归并排序中,需要使用一个临时数组来存储排序结果,如果临时数组的大小不够或者在操作数组时下标越界,会导致程序出错。

  3. 归并排序的稳定性:归并排序是一种稳定的排序算法,即排序后相同元素的相对位置不变。在实现归并排序时,需要注意保持排序的稳定性。

  4. 归并排序的时间和空间复杂度:归并排序的时间复杂度为O(nlogn),空间复杂度为O(n),在排序大规模数据时,可能会出现内存溢出等问题,需要注意。

  5. 优化归并排序:归并排序虽然时间复杂度很好,但是在实际应用中可能会出现一些效率问题。可以通过一些优化措施来提高归并排序的效率,例如使用循环代替递归、使用插入排序优化小数组的排序等。

三、习题

1.第k个数

支点选择出来后,选择递归的范围。

当k <= i,递归左区间 [l, i]。

当k >= j,递归右区间 [j, r]。

时间复杂度:

n + n / 2 + n / 4 + ... <= 2n
O(n)

#include<iostream>

class solution
{
public:
	int quick_sort(int q[], int l, int r, int k)
	{
		if (l >= r) return q[l];
		int x = q[(l + r) >> 1], i = l - 1, j = r + 1;
		while (i < j)
		{
			do i++; while (q[i] < x);
			do j--; while (q[j] > x);
			if (i < j) std::swap(q[i], q[j]);
		}
		if (k <= j) return quick_sort(q, l, j, k);
		return quick_sort(q, j + 1, r, k);
	}
};
int main()
{
    const int N = 1000;
	int q[N];
	int n, k;
	scanf("%d%d", &n, &k);

	for (int i = 0; i < n; i++) scanf("%d", &q[i]);

	std::cout << solution().quick_sort(q, 0, n - 1, k - 1) << std::endl;
    // 传入(k - 1)来指向第k小目标的坐标

    return 0;
}

2.数组中的逆序对*

 

 利用数组局部有序性,在归并过程中利用两指针之差来计算出对应的逆序数。

class Solution {
public:
	int reversePairs(vector<int>& nums)
	{
		int tmp[nums.size()];
		return merge_sort(nums, tmp, 0, nums.size() - 1);
	}
private:
	long merge_sort(vector<int>& q, int tmp[], int l, int r)
	{
		if (l >= r) return 0;
		int mid = (l + r) >> 1;
		long long res = merge_sort(q, tmp, l, mid) + merge_sort(q, tmp, mid + 1, r);

		int k = 0, i = l, j = mid + 1;
		while (i <= mid && j <= r)
			if (q[i] <= q[j]) tmp[k++] = q[i++];
			else
			{
				res += (mid + 1 - i);
				tmp[k++] = q[j++];
			}
		while (i <= mid) tmp[k++] = q[i++];
		while (j <= r) tmp[k++] = q[j++];
		
		for (i = l, j = 0; i <= r; i++, j++) q[i] = tmp[j];
		return res;
	}
};

tip:

leetcode上创建临时数组tmp必须要使用int来创建,用vector创建会导致超时的错误。

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

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

相关文章

数据结构---堆的实现

文章目录 前言一、什么是堆&#xff1f;二、堆的实现 1.堆的结构 2.接口实现总结 前言 堆(Heap)是计算机科学中一类特殊的数据结构&#xff0c;是最高效的优先级队列。堆通常是一个可以被看做一棵完全二叉树的数组对象。 一、什么是堆&#xff1f; 现实中我们通常把堆(一种二叉…

如何借助快解析实现Tomcat的外网访问

Tomcat深受Java爱好者喜爱&#xff0c;是一个免费开源的轻量级Web应用服务器&#xff0c;是开发调试JSP程序的首选。在项目开发中&#xff0c;常遇到需要远程调试或外网演示的情况&#xff0c;在没有公网IP、路由器不做映射的情况下&#xff0c;如何将Tomcat发布到外网&#xf…

推荐5款免费好用的chatGPT平台

1 ShellGPT 这是一款出色的客户端&#xff0c;无需APIkey和科学上网即可访问chatGPT3.5以及绘画AI。项目的github地址如下&#xff1a;https://github.com/akl7777777/free-chatgpt-client-pub/&#xff0c;可在主页下载windows、linux和macOS的安装包&#xff0c;安装后即可使…

【C++】线程库互斥量库原子性操作库

文章目录 线程库thread类的介绍线程对象的构造方式thread提供的成员函数获取线程的id的方式线程函数参数join与detach 互斥量库&#xff08;mutex&#xff09;mutex的种类lock_guard和unique_lock 原子性操作库&#xff08;atomic&#xff09;条件变量库&#xff08;condition_…

Docker中应用OpenDDS

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。 容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app)。几乎没有性能开销,可以很容易地在机器和数据…

【网络】网络基础协议概念IPMAC地址

文章目录 网络基础网络的发展历程网络在哪里的问题网络协议栈各部分所处位置&#xff1a;网络协议栈各层的作用网络协议栈分层的目的 网络协议的概念 网络协议协议分层的好处理解各层之间直接通信OSI七层模型TCP/IP五层&#xff08;或四层&#xff09;模型 网络传输基本流程同局…

一个简单的servlet应用

第一个 Servlet 程序 1. 创建项目 使用 IDEA 创建一个 Maven 项目. 1.1、File -> New Project Name:javaservlet2 Location:选择要存放的路径 Language:Java Build system:Maven 点击Create按钮 1.2、Pom.xml引入依赖 依赖包来源&#xff1a; <dependencies> …

kafka 学习,笔记

前置条件&#xff0c;需要安装Java 1 去官网下载Kafka安装包 2 将安装解压缩到C盘根目录 3 在cmd命令行窗口进入kafka是根目录 cd c:\kafka_2.12-3.4.0 4 启动zookeeper服务 卡夫卡的运行需要zookeeper的支持&#xff0c;一般来说我们需要安装zookeeper&#xff0c;但是卡夫卡…

C语言程序设计研究生考试大纲

适用于全部C语言程序设计自命题院校 1.单选&#xff08;30分&#xff09;。 2.判断&#xff08;15分&#xff09;。 3.程序阅读与分析&#xff08;45&#xff09;。 4.编程题&#xff08;60分&#xff09;。 考试总分&#xff1a;150分 考试时间&#xff1a;3小时 考试内容 一…

浏览器点击下载太 LOW,如何提高下载操作的逼格?

文章目录 Part.I IntroductionChap.I 预备知识Chap.II URL Part.II 下载的方式Chap.I PythonChap.II WgetChap.III Curl Reference Part.I Introduction 用浏览器下载东西需要一个一个点击&#xff0c;当需要批量下载的时候&#xff0c;这样操作不免有些繁琐。本文整理了常用的…

指示学习(Instruct Learning)和提示(Prompt Learning)学习区别

https://arxiv.org/pdf/2109.01652.pdf 提出instruct learning的论文 指示学习是谷歌Deepmind的Quoc V.Le团队在2021年的一篇名为《Finetuned Language Models Are Zero-Shot Learners》文章中提出的思想。指示学习和提示学习的目的都是去挖掘语言模型本身具备的知识。不同的是…

安全运营场景下的语言模型应用

接上篇&#xff0c;将安全运营的定义为“使用算法能力提取关键信息”&#xff0c;以此来规避算法误判漏判带来的责任问题&#xff0c;同时提升运营人员的工作效率。在这篇尝试对语言模型的使用方法做一下讨论和分享。 1. 语言模型 先聊一下语言模型。&#xff08;这里刻意规避…

【2023 年第十三届 MathorCup 高校数学建模挑战赛】C 题 电商物流网络包裹应急调运与结构优化问题 赛后总结之31页论文及代码

【2023 年第十三届 MathorCup 高校数学建模挑战赛】C 题 电商物流网络包裹应急调运与结构优化问题 1 题目 电商物流网络由物流场地&#xff08;接货仓、分拣中心、营业部等&#xff09;和物流场 地之间的运输线路组成&#xff0c;如图 1 所示。受节假日和“双十一”、“618”等…

计算机视觉(2)——图像预处理

目录 二、图像预处理 2.1 介绍 2.2 特征提取方法 2.2.1 直方图 2.2.2 CLAHE 2.2.3 形态学运算 2.2.4 空间域处理及其变换 2.2.5 空间域分析及变换 &#xff08;1&#xff09; 均值滤波 &#xff08;2&#xff09;中值滤波 &#xff08;3&#xff09;高斯滤波 &am…

【博弈论】【第一章】博弈论导论

博弈论导论 【例题】选择数字【例题】巴什博弈【例题】射手博弈博弈论的基本概念&#xff1a;参与人战略行动信息支付函数【例题】分100元 课程概述&#xff1a; 【例题】选择数字 两个参与人A和B&#xff0c;轮流选择[3,4,5,6,7,8,9]中的一个整数&#xff08;可重复)。当累计…

【JUC基础】01. 初步认识JUC

目录 1、前言 2、什么是JUC 3、并行和并发 4、进程和线程 5、如何创建子线程 5.1、继承Thread 5.2、实现Runnable 5.3、实现Callable 5.4、小结 6、Thread和Runnable 7、Runnable和Callable 8、线程状态 9、总结 1、前言 前段时间&#xff0c;有朋友跟我说&#…

(7) 支持向量机(上)

文章目录 1 概述1.1 支持向量机分类器是如何工作的 2 sklearn.svm.SVC2.1 线性SVM决策过程的可视化2.2 重要参数kernel&#xff08;核函数&#xff09;2.3 探索核函数在不同数据集上的表现2.4 探索核函数的优势和缺陷2.5 选取与核函数相关的参数&#xff1a;degree & gamma…

【Java笔试强训 27】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525; 不用加…

VSCode下载、安装和简单配置

之前提到Python IDE的选择时&#xff0c;VSCode以其轻便、简洁、高效、专业等优点成为最适合做Python工程项目开发的IDE&#xff0c;本期就来详细讲解一下VSCode的一个下载、安装以及Python开发环境的配置。 一、下载 直接进入VSCode官网&#xff0c;选择对应系统版本的VSCod…

切片、索引和排序

关于使用Series切片带尾片的疑惑。 切片是数字的时候不带尾片 切片非数字时带尾片 索引 可以使用loc()和iloc()选择数据。轴标签(loc())&#xff0c;整数标签(iloc())。 # 第一行列名为’A‘&#xff0c;’B‘的行。 print( df.loc[1, [A, B]])# [0, 1)的列为 [B(1), A(0…