交换排序(冒泡排序和快速排序)

一、基本思想

所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置。

交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

二、冒泡排序

1.核心思想

两两相邻的元素进行比较

2.动图展示

3.代码展示

void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}
void BubbleSort(int* a, int n)
{for (int j = 0; j < n; j++){// 单趟int flag = 0;for (int i = 1; i < n - j; i++){if (a[i - 1] > a[i]){Swap(&a[i - 1], &a[i]);flag = 1;}}if (flag == 0){break;}}
}

4.冒泡排序特性总结

①冒泡排序是一种非常容易理解的排序

②时间复杂度:O(N^2)

③空间复杂度:O(1)

④稳定性:稳定

三、快速排序

1.基本思想

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

// 假设按照升序对array数组中[left, right)区间中的元素进行排序
void QuickSort(int array[], int left, int right)
{if (right - left <= 1)return;// 按照基准值对array数组的 [left, right)区间中的元素进行划分int div = partion(array, left, right);// 划分成功后以div为边界形成了左右两部分 [left, div) 和 [div+1, right)// 递归排[left, div)QuickSort(array, left, div);// 递归排[div+1, right)QuickSort(array, div + 1, right);
}

上述为快速排序递归实现的主框架,发现与二叉树前序遍历规则非常像,同学们在写递归框架时可想想二叉树前序遍历规则即可快速写出来,后序只需分析如何按照基准值来对区间中数据进行划分的方式即可。

2.将区间按照基准值划分为左右两半部分的常见方式

①hoare版本

//简单版本的快排
void QuickSort(int* a, int left, int right)
{if (left >= right)return;int keyi = left;int begin = left, end = right;while (begin < end){// 右边找小while (begin < end && a[end] >= a[keyi]){--end;}// 左边找大while (begin < end && a[begin] <= a[keyi]){++begin;}Swap(&a[begin], &a[end]);}Swap(&a[keyi], &a[begin]);keyi = begin;// [left, keyi-1] keyi [keyi+1, right]QuickSort(a, left, keyi - 1);QuickSort(a, keyi + 1, right);
}

上面代码是简单版本的快速排序,但是上面代码还存在一些问题:存在栈溢出的风险(见下图)。

优化版本:

// 三数取中
int GetMidi(int* a, int left, int right)
{int midi = (left + right) / 2;// left midi rightif (a[left] < a[midi]){if (a[midi] < a[right]){return midi;}else if (a[left] < a[right]){return right;}else{return left;}}else // a[left] > a[midi]{if (a[midi] > a[right]){return midi;}else if (a[left] < a[right]){return left;}else{return right;}}
}
void QuickSort(int* a, int left, int right)
{if (left >= right)return;// 小区间优化,不再递归分割排序,减少递归的次数if ((right - left + 1) < 10){InsertSort(a + left, right - left + 1);}else{// 三数取中int midi = GetMidi(a, left, right);Swap(&a[left], &a[midi]);int keyi = left;int begin = left, end = right;while (begin < end){// 右边找小while (begin < end && a[end] >= a[keyi]){--end;}// 左边找大while (begin < end && a[begin] <= a[keyi]){++begin;}Swap(&a[begin], &a[end]);}Swap(&a[keyi], &a[begin]);keyi = begin;// [left, keyi-1] keyi [keyi+1, right]QuickSort(a, left, keyi - 1);QuickSort(a, keyi + 1, right);}
}

②前后指针版本

int PartSort2(int* a, int left, int right)
{// 三数取中int midi = GetMidi(a, left, right);Swap(&a[left], &a[midi]);int keyi = left;int prev = left;int cur = prev + 1;while (cur <= right){if (a[cur] < a[keyi] && ++prev != cur)Swap(&a[prev], &a[cur]);cur++;}Swap(&a[prev], &a[keyi]);return prev;
}
void QuickSort(int* a, int left, int right)
{if (left >= right)return;int keyi = PartSort2(a, left, right);// [left, keyi-1] keyi [keyi+1, right]QuickSort(a, left, keyi - 1);QuickSort(a, keyi + 1, right);
}

③非递归

循环每走一次,取栈顶区间,单趟排序,右子区间入栈。(先单趟,再整体)

#include"Stack.h"
void QuickSortNonR(int* a, int left, int right)
{ST st;STInit(&st);STPush(&st, right);STPush(&st, left);while (!STEmpty(&st)){int begin = STTop(&st);STPop(&st);int end = STTop(&st);STPop(&st);int keyi = PartSort2(a, begin, end);// [begin, keyi-1] keyi [keyi+1, end]if (keyi + 1 < end){STPush(&st, end);STPush(&st, keyi + 1);}if (begin < keyi - 1){STPush(&st, keyi - 1);STPush(&st, begin);}}STDestroy(&st);
}

3. 快速排序特性总结

①快速排序整体的综合性能和使用场景都是比较好的。

②时间复杂度:O(N*logN)。

③空间复杂度:O(logN)。

④稳定性:不稳定。

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

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

相关文章

6G网络的关键技术、应用前景与挑战并存的科技征途

移动通信技术正以前所未有的速度迭代更新&#xff0c;而6G技术的研发与商用化进程渐渐成为了当前科技领域的热点与焦点。在5G技术尚未完全普及的今天&#xff0c;全球各国已纷纷将目光投向了更加充满想象的6G网络时代。本文将探讨全球6G研发的最新进展&#xff0c;特别是欧盟与…

Linux进程间通信——互斥锁与信号量详解

文章目录 互斥锁信号量整形信号量记录形信号量利用信号量实现进程互斥利用信号量实现同步利用信号量实现前驱关系 互斥锁 现实中的锁有两种状态&#xff0c;打开和关闭&#xff0c;分别对应这资源可以被使用&#xff0c;和不可以被使用&#xff0c;我们可以通过使用钥匙对锁的…

<数据集>考场行为识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;2192张 标注数量(xml文件个数)&#xff1a;2192 标注数量(txt文件个数)&#xff1a;2192 标注类别数&#xff1a;2 标注类别名称&#xff1a;[cheating, good] 序号类别名称图片数框数1cheating128214412good1067…

优化uni-app页面间的传参跳转【兼容多端】

问题场景 options传值的想必用的都比较多&#xff0c;除了option传值的场景外&#xff0c;还有两个场景用的也比较多&#xff1a; 1&#xff09;传复杂对象 对于传递复杂对象options就有点力不从心了&#xff0c;毕竟URL模式GET传递参数的长度有限。此时需要采用eventChanne…

在多云生态下,如何实现跨云的自动化身份管理?

在多云环境下实现跨云的自动化身份管理是一个重要的课题&#xff0c;因为这可以帮助企业确保用户和应用程序能够在不同云服务提供商之间无缝地访问资源&#xff0c;同时保持高度的安全性和合规性。以下是一些关键技术和实践方法&#xff0c;用于实现跨云环境下的自动化身份管理…

Linux驱动开发基础(中断)

所学来自百问网 目录 1. 嵌入式中断系统 2. 中断处理流程 3. 异常向量表 4. Linux系统对中断的处理 4.1 ARM 处理器程序运行的过程 4.2 保护现场 5. Linux 系统对中断处理的演进 5.1 硬件中断和软件中断 5.2 中断拆分(上半部和下半部) 5.2.1 tasklet 5.2.2 工作队列…

git笔记:git常用命令备忘录

1、工作区域和文件状态 1.1、工作区域 git的数据管理分为四个区域&#xff1a; 工作区&#xff08;Working Directory&#xff09; 本地工作目录&#xff0c;是我们电脑上的目录&#xff0c;是我们实际编写代码的区域&#xff0c;修改完工作区的文件后可以使用git add命令将…

72 华为资源库

1 报文格式 https://info.support.huawei.com/info-finder/tool/zh/enterprise/packetformat 2 华为IP网络电子书 资源可以下载 https://e.huawei.com/cn/topic/enterprise-network/ip-ebook 3 华为产品文档 https://support.huawei.com/enterprise/zh/doc/index.html 4 华为…

【HuggingFace Transformers】BertSelfOutput 和 BertOutput源码解析

BertSelfOutput 和 BertOutput源码解析 1. 介绍1.1 共同点(1) 残差连接 (Residual Connection)(2) 层归一化 (Layer Normalization)(3) Dropout(4) 线性变换 (Linear Transformation) 1.2 不同点(1) 处理的输入类型(2) 线性变换的作用(3) 输入的特征大小 2. 源码解析2.1 BertSe…

Facebook的AI助手:如何提升用户社交体验的智能化

在现代社交媒体平台中&#xff0c;人工智能&#xff08;AI&#xff09;的应用正逐渐改变人们的社交体验。Facebook作为全球最大的社交媒体平台之一&#xff0c;已在AI技术的开发与应用上投入了大量资源&#xff0c;并通过其AI助手为用户提供了更加个性化、智能化的互动体验。这…

vagrant 创建虚拟机

创建一个名为 “Vagrantfile” 的文件&#xff0c;修改如下内容&#xff1a; Vagrant.configure("2") do |config|(1..3).each do |i|config.vm.define "k8s-node#{i}" do |node|# 设置虚拟机的Boxnode.vm.box "centos/7"# 设置虚拟机的主机名…

逆向中的游戏-入土为安的第二十五天

逆向中的游戏 CE的介绍 Cheat Engine &#xff0c;简称CE&#xff0c;是逆向工程师常用的几大神器之一&#xff0c;也是游戏汉化、破解以及外挂编写中常用的工具&#xff0c;其功能包括&#xff1a;内存扫描、十六进制编辑器、调试工具&#xff0c;可以进行反汇编调试、断点跟…

代码随想录算法训练营_day28

题目信息 122. 买卖股票的最佳时机 II 题目链接: https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/题目描述: 给你一个整数数组 prices &#xff0c;其中 prices[i] 表示某支股票第 i 天的价格。 在每一天&#xff0c;你可以决定是否购买和/或出售股票。你…

Springboot-RequestContextHolder

RequestContextHolder 是 Spring 框架中的一个类,主要用于在多线程环境中存储和访问 HTTP 请 求的上下文信息。它允许在 Spring 应用程序中从任何位置访问当前请求的相关信息,比如 HTTP 头部、会话数据等,而无需将请求对象直接传递到每个方法中。 主要用途 存储请求上下…

Seata 学习

简介 我们都知道 Seata 是一个分布式事务的解决方案&#xff0c;今天我们就来带大家了解一下什么是分布式事务&#xff0c;首先我们先来了解一下基础的知识——事务&#xff0c;我们先来了解一下事务的概念是什么。 基本概念 事务四部分构成— ACID&#xff1a; A(Atomic)&…

小程序路由传参和获取页面栈方法

路由方法 navigateTo, redirectTo 只能打开非 tabBar 页面。switchTab 只能打开 tabBar 页面。reLaunch 可以打开任意页面。页面底部的 tabBar 由页面决定&#xff0c;即只要是定义为 tabBar 的页面&#xff0c;底部都有 tabBar。调用页面路由带的参数可以在目标页面的onLoad中…

matlab 计算复共轭

目录 一、概述1、算法概述2、主要函数二、代码示例1、求复数的复共轭2、求矩阵中复数值的复共轭三、参考链接本文由CSDN点云侠翻译,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的抄袭狗。 一、概述 1、算法概述 2、主要函数 Zc = conj(Z)返回 Z …

【python】Python中小巧的异步web框架Sanic快速上手实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

理解torch.argmax() ,我是错误的

torch.max() import torch# 定义张量 b b torch.tensor([[1, 3, 5, 7],[2, 4, 6, 8],[11, 12, 13, 17]])# 使用 torch.max() 找到最大值 max_indices torch.max(b, dim0)print(max_indices) 输出&#xff1a;>>> print(max_indices) torch.return_types.max( valu…

【13.3 python中的高级文件操作】

python中的高级文件操作 在Python中&#xff0c;除了基本的文件读写和目录操作外&#xff0c;还有一些高级的文件和目录操作&#xff0c;如删除文件、重命名文件和目录、以及获取文件的基本信息等。这些操作通常通过os模块和pathlib模块来实现。下面我将详细介绍这些操作&#…