几种排序算法(2)

  • 1冒泡排序
  • 2.快速排序
    • 2.1hoare版本找基准值
    • 2.2lomuto前后指针
  • 3.非递归版本快速排序
  • 4.递归排序
  • 5.排序算法复杂度及稳定性分析

我们已经详解了插入排序和选择排序,不了解的可以翻看我上一篇博客。

1冒泡排序

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

每次循环都会找到最大的元素放到最后一个位置上,以此往复完成排序。
如果在某一次循环exchange变成0,说明数组已然有序,直接退出循环即可。
时间复杂度:O(N^2 )
空间复杂度:O(1)

2.快速排序

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

void QuickSort(int* a, int left, int right)
{if (left >= right) {return;}//_QuickSort⽤于按照基准值将区间[left,right)中的元素进⾏划分 int meet = _QuickSort(a, left, right);QuickSort(a, left, meet - 1);QuickSort(a, meet + 1, right);
}

_QuickSort这个函数应该怎么设计呢?

2.1hoare版本找基准值

int _QuickSort(int* a, int left, int right)
{int keyi = left;left++;while (left <= right){//right:从右往左找比基准值小的while (left <= right && a[right] > a[keyi]){right--;}//left:从左往右找比基准值大的while (left <= right && a[left] < a[keyi]){left++;}if (left <= right){Swap(&a[left++], &a[right--]);}}Swap(&a[keyi], &a[right]);//与小于基准值的交换return right;
}

2.2lomuto前后指针

设计两个指针,cur指针负责遍历整个数组并找见比基准值小的并于prev指向的交换,每次两个指针都++,如果cur遇见比基准值大的prev就不动,直到遇到小于基准值的就另++prev指向的数据与cur指向的交换
在这里插入图片描述

int _QuickSort(int* a, int left, int right)
{int prev = left, cur = left + 1;int key = left;while (cur <= right){if (a[cur] < a[key] && ++prev != cur){swap(&a[cur], &a[prev]);}++cur;}swap(&a[key], &a[prev]);return prev;
}

时间复杂度:O(nlogn)
空间复杂度:O(logn)

3.非递归版本快速排序

这里就用到了我们前面实现的栈了。
我们知道,在快速排序中,数组中元素的交换是发生在找基准值这个过程中的,所以我们可以在栈中不断放入left与right.直到栈为空。

void QuickSortNorR(int* arr, int left, int right)
{ST st;STInit(&st);STPush(&st,right);STPush(&st,left);while (!STEmpty(&st)){//取栈顶两次int begini = STTop(&st);STPop(&st);int endi = STTop(&st);STPop(&st);//找基准值int keyi = _QuickSort(arr, begini, endi);if (keyi+1 < endi)//右序列[keyi+1,endi]{STPush(&st,endi);STPush(&st,keyi+1);}if (keyi -1> begini)//左序列[begini,keyi-1]{STPush(&st,keyi-1);STPush(&st,begini);}}Destroy(&st);
}

我们可以看到,这个版本中的逻辑其实也跟递归类似,都是一条路走到黑,直到序列中的left与rihgt不符合找基准值的条件。

4.递归排序

这张图可以很好解释归并排序的思想,我们想要将数组拆分成多个子数组,将这多个子数组都变成有序,合并
在这里插入图片描述

void _MergrSort(int* arr, int left, int right,int*tmp)
{//分解if (left >= right){return;}int mid = (left + right) / 2;_MergrSort(arr, left, mid,tmp);_MergeSort(arr, mid + 1, right,tmp);//当程序走到这里时,[left,mid],[mid+1,right]已经变成两个有序数组//合并两个有序数组int begin1 = left;int end1 = mid;int begin2 = mid + 1;int end2 = right;int index = left;while (begin1 <= end1 && begin2 <= end2){if (arr[begin1] < arr[begin2]){tmp[index++] = arr[begin1++];}else{tmp[index++] = arr[begin2++];}}for (int i = left;i <= right;i++){arr[i] = tmp[i];}}
void MergeSort(int* arr, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);_MergeSort(arr, 0, n - 1,tmp);free(tmp);
}

时间复杂度:O(nlogn)
空间复杂度:O(n)

5.排序算法复杂度及稳定性分析

稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,⽽在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。
在这里插入图片描述
在这里插入图片描述

如果发现错误,欢迎打在评论区。
主页还有更多优质内容OvO

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

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

相关文章

Excel甘特图

1. 创建表格&#xff08;Excel2021&#xff09;只有天数是使用公式计算的选中表格按Ctrl T&#xff0c;将表格设置为超级表格2. 创建堆积条形图3. 添加设置图例项3.1 添加开始时间3.2 修改图例项顺序 3.3 编辑轴标签3.4 Y轴逆序类别 3.5 添加开始时间数据标签选择 所用橘色图&…

基于OpenCV的答题卡自动识别与评分系统

引言 在教育考试场景中&#xff0c;手动批改答题卡效率低下且容易出错。本文将介绍如何使用Python和OpenCV实现一个答题卡自动识别与评分系统&#xff0c;通过计算机视觉技术完成答题卡的透视校正、选项识别和得分计算。该系统可广泛应用于学校考试、培训测评等场景&#xff0c…

LLaMA-MoE v2:基于后训练混合专家模型的稀疏性探索与技术突破

重新定义大型语言模型的效率边界在人工智能飞速发展的今天&#xff0c;大型语言模型&#xff08;LLMs&#xff09;已成为推动技术进步的核心力量。然而&#xff0c;模型规模的不断扩大带来了惊人的计算成本和高昂的部署门槛&#xff0c;使得众多研究机构和中小型企业难以承担。…

R geo 然后读取数据的时候 make.names(vnames, unique = TRUE): invalid multibyte string 9

setwd("K:/download/geo") # 替换为实际工作目录 # 修改get_geo_data_local函数中的读取部分 #file_path <- "K:/download/geo/raw_data/GEO/GSE32967_series_matrix_fixed.txt" file_path <- "K:/download/geo/data/GSE32967_series_matrix.t…

深入理解 Spring @Async 注解:原理、实现与实践

在现代 Java 应用开发中&#xff0c;异步编程是提升系统吞吐量和响应速度的关键技术之一。Spring 框架提供的Async注解极大简化了异步方法的实现&#xff0c;让开发者无需手动管理线程即可轻松实现异步操作。本文将从底层原理到实际应用&#xff0c;全面解析Async注解的工作机制…

linux C 语言开发 (七) 文件 IO 和标准 IO

文章的目的为了记录使用C语言进行linux 开发学习的经历。开发流程和要点有些记忆模糊&#xff0c;赶紧记录&#xff0c;防止忘记。 相关链接&#xff1a; linux C 语言开发 (一) Window下用gcc编译和gdb调试 linux C 语言开发 (二) VsCode远程开发 linux linux C 语言开发 (…

maven , mvn 运行 项目

提示&#xff1a;环境搭建 文章目录前言一、使用步骤1. 以构建含有 pom.xml 的项目2.mvn 运行具体项目3.mvn 指定模块>运行具体项目前言 提示&#xff1a;版本 spirngboot 3.2 jdk 21 mvn 3.9 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、使…

JVM垃圾回收的时机是什么时候(深入理解 JVM 垃圾回收时机:什么时候会触发 GC?)

深入理解 JVM 垃圾回收时机&#xff1a;什么时候会触发 GC&#xff1f;在 Java 开发中&#xff0c;我们常听说 “JVM 会自动进行垃圾回收”&#xff0c;但很少有人能说清&#xff1a;GC 究竟在什么情况下会被触发&#xff1f;是到固定时间就执行&#xff1f;还是内存满了才会启…

在Vue项目中Axios发起请求时的小知识

在Vue项目中Axios发起请求时的小知识 在Vue项目开发中&#xff0c;Axios作为基于Promise的HTTP客户端&#xff0c;凭借其简洁的API设计和强大的功能&#xff08;如请求/响应拦截、自动JSON转换、取消请求等&#xff09;&#xff0c;已成为前端与后端通信的主流选择。本文将深入…

GeoHash分级索引技术

GeoHash分级索引技术是一种将二维地理坐标转换为一维字符串的空间索引方法,其核心是通过分级网格划分和前缀编码实现高效的空间数据检索。以下从技术原理、实现细节到工程优化展开详细解析: 一、编码原理与分级结构 1. 经纬度二进制化 GeoHash通过递归二分地球表面生成网格…

HTML HTML基础(4)

1.列表 (1).有序列表 概念&#xff1a;有顺序或侧重顺序的列表。 <h2>要把大象放冰箱总共分几步</h2> <ol> <li>把冰箱门打开</li> <li>把大象放进去</li> <li>把冰箱门关上</li> </ol> (2).无序列表 概念&a…

MySQL中的回表操作

在数据库查询&#xff08;尤其是基于 B树索引 的关系型数据库&#xff0c;如MySQL、PostgreSQL&#xff09;中&#xff0c;“回表”是一个核心且高频出现的概念&#xff0c;直接影响查询性能。要理解回表&#xff0c;需先理清索引结构与数据存储的关联&#xff0c;再拆解其发生…

QT子线程与GUI线程安全交互

在Qt应用程序开发中&#xff0c;涉及到多线程处理时&#xff0c;如何安全地从子线程更新UI界面是一个常见的问题。Qt的UI界面并不是线程安全的&#xff0c;意味着你不能直接在子线程中操作UI组件&#xff08;比如按钮、标签等&#xff09;。如果不遵循线程安全的规则&#xff0…

RL【10-2】:Actor - Critic

系列文章目录 Fundamental Tools RL【1】&#xff1a;Basic Concepts RL【2】&#xff1a;Bellman Equation RL【3】&#xff1a;Bellman Optimality Equation Algorithm RL【4】&#xff1a;Value Iteration and Policy Iteration RL【5】&#xff1a;Monte Carlo Learnin…

开源大模型天花板?DeepSeek-V3 6710亿参数MoE架构深度拆解

文章目录认知解构&#xff1a;DeepSeek的定位与核心价值模型概述与发展历程创立初期与技术奠基&#xff08;2023年7月-2024年11月&#xff09;里程碑一&#xff1a;MoE架构规模化突破&#xff08;2024年12月&#xff09;里程碑二&#xff1a;推理成本革命性优化&#xff08;202…

10 训练中的一些问题

&#x1f31f; 大背景&#xff1a;训练神经网络 下山寻宝 训练神经网络就像你蒙着眼在一座大山里&#xff0c;想找最低点&#xff08;最小损失&#xff09;。你只能靠脚下的坡度&#xff08;梯度&#xff09;来决定往哪儿走。 你的位置 模型参数&#xff08;权重 www&#xf…

synchronized锁升级的过程(从无锁到偏向锁,再到轻量级锁,最后到重量级锁的一个过程)

锁升级是 Java 中 synchronized 锁 的核心优化机制&#xff08;基于 JVM 的 对象头 Mark Word 实现&#xff09;&#xff0c;指锁的状态从 无锁 → 偏向锁 → 轻量级锁 → 重量级锁 逐步升级的过程。其目的是通过 “按需升级”&#xff0c;在不同并发场景下选择最优的锁实现&am…

HOT100--Day25--84. 柱状图中最大的矩形,215. 数组中的第K个最大元素,347. 前 K 个高频元素

HOT100–Day25–84. 柱状图中最大的矩形&#xff0c;215. 数组中的第K个最大元素&#xff0c;347. 前 K 个高频元素 每日刷题系列。今天的题目是《力扣HOT100》题单。 题目类型&#xff1a;栈&#xff0c;堆。 84. 柱状图中最大的矩形 思路&#xff1a; class Solution {publ…

基于 Apache Doris 的用户画像数据模型设计方案

一、 需求分析与设计目标数据源&#xff1a;用户基本信息&#xff1a;用户ID、性别、出生日期、注册时间、常驻地域&#xff08;省、市、区&#xff09;、职业等。用户体检报告&#xff1a;每次体检的报告ID、体检时间、各项指标&#xff08;如血压、血糖、血脂、BMI等&#xf…

Python的深度学习

深入理解Python高级特性掌握Python的高级特性是进阶的关键&#xff0c;包括装饰器、生成器、上下文管理器、元类等。这些特性能够提升代码的灵活性和效率。例如&#xff0c;装饰器可以用于实现AOP&#xff08;面向切面编程&#xff09;&#xff0c;生成器可以处理大数据流而无需…