两种交换排序算法--冒泡,快速
目录
1.冒泡排序原理
2.快速排序原理
3.冒泡代码实现
4.快速排序代码实现
1.冒泡排序原理
冒泡排序(Bubble Sort)是一种简单的排序算法,基本思想是通过反复交换相邻的元素,直到整个序列有序。它的名字来源于较大的元素像气泡一样“浮”到序列的顶部。
原理:
-
初始状态:我们从数组的第一个元素开始,比较相邻的两个元素。如果第一个元素大于第二个元素,就交换它们的位置;如果不大,则继续比较下一对元素。
-
第一轮排序:通过一轮比较后,最大的元素会被“冒泡”到数组的最后面。
-
继续排序:接着,我们对剩下的未排序部分继续进行类似的比较和交换,直到剩下的部分只有一个元素,意味着数组已经排序完成。
示例:
假设有一个数组 [5, 2, 9, 1, 5, 6],我们来演示一下冒泡排序的过程。
-
第一次遍历:
- 比较
5和2,交换,得到[2, 5, 9, 1, 5, 6] - 比较
5和9,不交换 - 比较
9和1,交换,得到[2, 5, 1, 9, 5, 6] - 比较
9和5,交换,得到[2, 5, 1, 5, 9, 6] - 比较
9和6,交换,得到[2, 5, 1, 5, 6, 9] - 第一轮结束,最大元素
9已经“冒泡”到最后。
- 比较
-
第二轮遍历:
- 比较
2和5,不交换 - 比较
5和1,交换,得到[2, 1, 5, 5, 6, 9] - 比较
5和5,不交换 - 比较
5和6,不交换 - 第二轮结束,最大元素
6已经排好位置。
- 比较
以此类推,直到所有元素都排好顺序。
时间复杂度:
- 最好的情况(已经有序):O(n)
- 最坏的情况(逆序):O(n²)
- 平均情况:O(n²)
虽然冒泡排序简单易懂,但由于其时间复杂度较高,通常在处理大数据时效率不高。
2.快速排序原理
快速排序(Quick Sort)是一种效率很高的排序算法,采用分治法(Divide and Conquer)的策略。它通过选择一个“基准”元素(pivot),然后将数组分成两部分:一部分比基准小,另一部分比基准大。接着递归地对这两部分分别进行快速排序,最终得到有序数组。
快速排序的基本原理:
-
选择基准元素:从数组中选择一个元素作为“基准”(pivot)。基准的选择方式可以有多种,比如选择第一个元素、最后一个元素、随机选择等。
-
分区操作:将数组重新排列,确保基准元素左边的元素都比它小,右边的元素都比它大。此时,基准元素已经排好位置了。
-
递归排序:对基准元素左边和右边的子数组分别进行快速排序。
-
终止条件:当子数组的长度为1或0时,递归终止,因为已经有序。
示例:
假设我们有一个数组 [10, 7, 8, 9, 1, 5],我们来演示一下快速排序的过程。我们选择最后一个元素 5 作为基准。
-
第一轮分区:
- 从左到右扫描数组,将小于基准元素的放左边,大于基准元素的放右边。最终,数组被分为
[1, 5, 8, 9, 7, 10],基准5排在了正确的位置。 - 此时,基准元素
5处于正确位置,左边的部分[1]和右边的部分[8, 9, 7, 10]需要继续排序。
- 从左到右扫描数组,将小于基准元素的放左边,大于基准元素的放右边。最终,数组被分为
-
递归对左部分排序:左边部分只有一个元素
[1],已经有序,不需要做任何操作。 -
递归对右部分排序:右边部分
[8, 9, 7, 10],选择基准元素10:- 分区后得到
[8, 9, 7, 10],基准元素10排在了正确的位置。 - 然后继续对
[8, 9, 7]排序。
- 分区后得到
-
继续递归分区:
- 对
[8, 9, 7]选择基准7,分区后得到[7, 9, 8]。 - 对
[9, 8]进行排序,最终得到[7, 8, 9]。
- 对
经过递归排序,最终得到有序的数组 [1, 5, 7, 8, 9, 10]。
快速排序的时间复杂度:
- 最优情况:当每次分区操作都能将数组均匀分成两部分时,时间复杂度是 O(n log n)。
- 最坏情况:当数组已经是升序或降序时,每次分区只能将一个元素排到正确位置,时间复杂度为 O(n²)。
- 平均情况:O(n log n),这是最常见的情况,且快速排序在大多数情况下都非常高效。
空间复杂度:
快速排序的空间复杂度通常为 O(log n),因为递归的深度最多为 log n(最好的情况下),但它是一个原地排序算法,不需要额外的存储空间。
优缺点:
- 优点:快速排序通常比其他 O(n log n) 排序算法(如归并排序)更高效,特别是对于大规模数据。
- 缺点:最坏情况下时间复杂度较高(O(n²)),但在实际应用中,通过优化基准元素的选择(比如三数取中法)可以有效避免这种情况。
3.冒泡代码实现
#include <stdio.h>
#include <stdlib.h>
#include <time.h>//冒泡排序typedef int ElemType;//顺序表
typedef struct SqList {ElemType* data;//指针,指向一块内存的起始地址int length;//存储动态数组的长度
}SqList;//顺序表初始化
void initSqList(SqList& L, int len) {L.length = len;L.data = (ElemType*)malloc(sizeof(ElemType) * L.length);//分配空间srand(time(NULL));//随机数生成for (int i = 0; i < L.length; i++){L.data[i] = rand() % 100;//随机生成数字存入顺序表,对100取余是为了规范存入的数据是0-99}
}//顺序表打印
void printSqList(SqList L) {for (int i = 0; i < L.length; i++){printf("%3d", L.data[i]);}printf("\n");
}void swap(ElemType& a, ElemType& b) {ElemType temp = a;a = b;b = temp;
}//冒泡排序顺序表中的元素
void bubbleSort(ElemType* arr, int length) {for (int i = 0; i < length - 1; i++) { //外层循环,控制循环次数,最多n-1次bool flag = false; // 标记本趟排序是否发生交换for (int j = length - 1; j > i; j--) { //内层循环,从后往前通过比较冒出本趟最小元素if (arr[j - 1] > arr[j]) { //小于前一个元素则交换swap(arr[j - 1], arr[j]);flag = true;}}if (flag == false) { //本趟没有交换,说明有序,结束return;}}
}int main() {SqList L;//定义一个顺序表initSqList(L, 10);//初始化顺序表,分配10个空间printSqList(L);//打印顺序表中的值 bubbleSort(L.data, 10);//将顺序表进行排序printSqList(L);return 0;
}
4.快速排序代码实现
#include <stdio.h>
#include <stdlib.h>
#include <time.h>//快速排序typedef int ElemType;//顺序表
typedef struct SqList {ElemType* data;//指针,指向一块内存的起始地址int length;//存储动态数组的长度
}SqList;//顺序表初始化
void initSqList(SqList& L, int len) {L.length = len;L.data = (ElemType*)malloc(sizeof(ElemType) * L.length);//分配空间srand(time(NULL));//随机数生成for (int i = 0; i < L.length; i++){L.data[i] = rand() % 100;//随机生成数字存入顺序表,对100取余是为了规范存入的数据是0-99}
}//顺序表打印
void printSqList(SqList L) {for (int i = 0; i < L.length; i++){printf("%3d", L.data[i]);}printf("\n");
}void swap(ElemType& a, ElemType& b) {ElemType temp = a;a = b;b = temp;
}// 分割数组
int partition(ElemType* arr, int low, int high) {ElemType pivot = arr[low]; //将当前第一个元素作为枢轴元素,划分数组while (low < high) { //外层循环,low和high相遇时为枢轴元素的最终位置while (low < high && arr[high] >= pivot) //从后往前找到第一个小于枢轴的元素跳出循环--high;arr[low] = arr[high]; //将小于枢轴的元素移到左端while (low < high && arr[low] <= pivot) //从前往后找到第一个大于枢轴的元素跳出循环++low;arr[high] = arr[low]; //将大于枢轴的元素移到右端}arr[low] = pivot; //枢轴元素放入最终位置return low; //返回枢轴的最终位置
}// 快速排序顺序表中的元素
void quickSort(ElemType* arr, int low, int high) {if (low < high) { //递归结束条件//将表分为两个子表,枢轴元素是中间值,左子表小于它,右子表大于它int pivotpos = partition(arr, low, high); //枢轴元素已放入最终位置quickSort(arr, low, pivotpos - 1); //依次递归处理两个子表quickSort(arr, pivotpos + 1, high);}
}int main() {SqList L;//定义一个顺序表initSqList(L, 10);//初始化顺序表,分配10个空间printSqList(L);//打印顺序表中的值quickSort(L.data, 0, 9);//将顺序表进行排序printSqList(L);return 0;
}
相关文章:
两种交换排序算法--冒泡,快速
目录 1.冒泡排序原理 2.快速排序原理 3.冒泡代码实现 4.快速排序代码实现 1.冒泡排序原理 冒泡排序(Bubble Sort)是一种简单的排序算法,基本思想是通过反复交换相邻的元素,直到整个序列有序。它的名字来源于较大的元素像气泡…...
循序渐进kubernetes-RBAC(Role-Based Access Control)
文章目录 概要Kubernetes API了解 Kubernetes 中的 RBACRoles and Role Bindings:ClusterRoles and ClusterRoleBindings检查访问权限:外部用户结论 概要 Kubernetes 是容器化应用的强大引擎,但仅仅关注部署和扩展远远不够,集群的安全同样至…...
《从因果关系的角度学习失真不变表示以用于图像恢复》学习笔记
paper:2303.06859 GitHub:lixinustc/Causal-IR-DIL: Distortion invariant feature learning for image restoration from a causality perspective 2023 CVPR 目录 摘要 1、介绍 1.1 图像修复任务 1.2 失真不变表示学习 1.3 因果效应估计的挑战…...
亚博microros小车-原生ubuntu支持系列:16 机器人状态估计
本来想测试下gmapping建图,但是底层依赖了yahboomcar_bringup做底层的数据处理,所以先把依赖的工程导入。 程序启动后,会订阅imu和odom数据,过滤掉一部分的imu数据后,然后与odom数据进行融合,最后输出一个…...
Greenplum临时表未清除导致库龄过高处理
1.问题 Greenplum集群segment后台日志报错 2.回收库龄 master上执行 vacuumdb -F -d cxy vacuumdb -F -d template1 vacuumdb -F -d rptdb 3.回收完成后检查 仍然发现segment还是有库龄报警警告信息发出 4.检查 4.1 在master上检查库年龄 SELECT datname, datfrozen…...
【Unity3D】实现横版2D游戏角色二段跳、蹬墙跳、扶墙下滑
目录 一、二段跳、蹬墙跳 二、扶墙下滑 一、二段跳、蹬墙跳 GitHub - prime31/CharacterController2D 下载工程后直接打开demo场景:DemoScene(Unity 2019.4.0f1项目环境) Player物体上的CharacterController2D,Mask添加Wall层…...
mybatis(134/134)完结
一级缓存(默认情况下开启)同一个sqlsession中执行相同的查询语句走一级缓存 二级缓存 :同一个sqlsessionfactory,sqlsession关闭了才会将一级缓存提交到二级缓存中 外部编写的缓存 PageHelper插件:方便进行分页&#x…...
PaddleSeg 从配置文件和模型 URL 自动化运行预测任务
git clone https://github.com/PaddlePaddle/PaddleSeg.git# 在ipynb里面运行 cd PaddleSegimport sys sys.path.append(/home/aistudio/work/PaddleSeg)import os# 配置文件夹路径 folder_path "/home/aistudio/work/PaddleSeg/configs"# 遍历文件夹,寻…...
人工智能丨视觉识别在自动化测试中的应用
视觉识别:自动化测试的新纪元 在当今快速发展的科技时代,软件测试正面对着日益复杂的挑战。作为其中一个关键领域,自动化测试不断寻求创新的方法,以提高测试效率和准确性。在这一背景下,视觉识别技术的引入为自动化测…...
lambda 表达式:Python中的极简艺术
lambda 表达式:Python中的极简艺术 — 让你的代码更简洁、更高效! 引言 在 Python 中,lambda 表达式是一种简洁的定义匿名函数的方式。它通常用于需要函数对象的场景,但又不需要显式定义一个完整函数的场合。本文将详细介绍 la…...
BLE透传方案,IoT短距无线通信的“中坚力量”
在物联网(IoT)短距无线通信生态系统中,低功耗蓝牙(BLE)数据透传是一种无需任何网络或基础设施即可完成双向通信的技术。其主要通过简单操作串口的方式进行无线数据传输,最高能满足2Mbps的数据传输速率&…...
无用知识研究:对std::common_type以及问号表达式类型的理解
先说结论:如果问号表达式能编译通过,那么std::common_type就能通过。因为common_type的底层依赖的就是?: common_type的实现里,利用了问号表达式:ternary conditional operator (?:) https://stackoverflow.com/questions/1432…...
苍穹外卖—订单模块
该模块分为地址表的增删改查、用户下单、订单支付三个部分。 第一部分地址表的增删改查无非就是对于单表的增删改查,较基础,因此直接导入代码。 地址表 一个用户可以有多个地址,同时有一个地址为默认地址。用户还可为地址添加例如&q…...
「 机器人 」扑翼飞行器的数据驱动建模核心方法
前言 数据驱动建模可充分利用扑翼飞行器的已有运行数据,改进动力学模型与控制策略,并对未建模动态做出更精确的预测。在复杂的非线性飞行环境中,该方法能有效弥补传统解析建模的不足,具有较高的研究与应用价值。以下针对主要研究方向和实现步骤进行整理与阐述。 1. 数据驱动…...
openeuler 22.03 lts sp4 使用 cri-o 和 静态 pod 的方式部署 k8s-v1.32.0 高可用集群
前情提要 整篇文章会非常的长…可以选择性阅读,另外,这篇文章是自己学习使用的,用于生产,还请三思和斟酌 静态 pod 的部署方式和二进制部署的方式是差不多的,区别在于 master 组件的管理方式是 kubectl 还是 systemctl有 kubeadm 工具,为什么还要用静态 pod 的方式部署?…...
Helm Chart 实战指南
Helm 是 Kubernetes 的包管理工具,而 Helm Chart 是 Helm 的核心概念,用于定义、安装和升级 Kubernetes 应用。本文将带你从零开始,通过实战演练,掌握 Helm Chart 的创建、配置和部署,帮助你高效管理 Kubernetes 应用。 1. 环境准备 在开始之前,确保你已经具备以下环境:…...
【数据结构】_顺序表经典算法OJ(力扣版)
目录 1. 移除元素 1.1 题目描述及链接 1.2 解题思路 1.3 程序 2. 合并两个有序数组 1.1 原题链接及题目描述 1.2 解题思路 1.3 程序 1. 移除元素 1.1 题目描述及链接 原题链接:27. 移除元素 - 力扣(LeetCode) 题目描述:…...
目前市场主流的AI PC对于大模型本地部署的支持情况分析-Deepseek
以下是目前市场主流AI PC对**大模型本地部署支持情况**的综合分析,结合硬件能力、软件生态及厂商动态进行总结: --- ### **一、硬件配置与算力支持** 1. **核心处理器架构** - **异构计算方案(CPUGPUNPU)**:主流…...
Vue3 v-bind 和 v-model 对比
1. 基本概念 1.1 v-bind 单向数据绑定从父组件向子组件传递数据简写形式为 : 1.2 v-model 双向数据绑定父子组件数据同步本质是 v-bind 和 v-on 的语法糖 2. 基础用法对比 2.1 表单元素绑定 <!-- v-bind 示例 --> <template><input :value"text&quo…...
MySQL分表自动化创建的实现方案(存储过程、事件调度器)
《MySQL 新年度自动分表创建项目方案》 一、项目目的 在数据库应用场景中,随着数据量的不断增长,单表存储数据可能会面临性能瓶颈,例如查询、插入、更新等操作的效率会逐渐降低。分表是一种有效的优化策略,它将数据分散存储在多…...
接口技术-第6次作业
目录 作业内容 解答 1.假设在一个系统中,8255A的端口地址为184H-187H,A口工作于方式1输出,B口工作于方式1输入,禁止中断,C口剩余的两根线PC5,PC4位输入,如下图所示,试编写初始化…...
计算机网络之计算机网络体系结构
一、定义与概述 计算机网络体系结构是计算机网络及其部件所应该完成功能的精确定义,这些功能由何种硬件或软件完成是遵循这种体系结构的。体系结构是抽象的,实现是具体的,是运行在计算机软件和硬件之上的。 二、主流模型 目前,…...
(1)Linux高级命令简介
Linux高级命令简介 在安装好linux环境以后第一件事情就是去学习一些linux的基本指令,我在这里用的是CentOS7作演示。 首先在VirtualBox上装好Linux以后,启动我们的linux,输入账号密码以后学习第一个指令 简介 Linux高级命令简介ip addrtou…...
网络直播时代的营销新策略:基于受众分析与开源AI智能名片2+1链动模式S2B2C商城小程序源码的探索
摘要:随着互联网技术的飞速发展,网络直播作为一种新兴的、极具影响力的媒体形式,正逐渐改变着人们的娱乐方式、消费习惯乃至社交模式。据中国互联网络信息中心数据显示,网络直播用户规模已达到3.25亿,占网民总数的45.8…...
CSS(快速入门)
欢迎大家来到我的博客~欢迎大家对我的博客提出指导,有错误的地方会改进的哦~点击这里了解更多内容 目录 一、什么是CSS?二、基本语法规范三、CSS选择器3.1 标签选择器3.2 id选择器3.3 class选择器3.4 通配符选择器3.5 复合选择器 四、常用CSS样式4.1 color4.2 font…...
waitpid使用
waitpid 是 Unix/Linux 系统中用于等待子进程状态变化的系统调用。它允许父进程挂起执行,直到指定的子进程终止或者发生了其他指定的状态变化。 waitpid 的语法 pid_t waitpid(pid_t pid, int *status, int options); pid: 要等待的子进程的进程 ID,特殊…...
对顾客行为的数据分析:融入2+1链动模式、AI智能名片与S2B2C商城小程序的新视角
摘要:随着互联网技术的飞速发展,企业与顾客之间的交互方式变得日益多样化,移动设备、社交媒体、门店、电子商务网站等交互点应运而生。这些交互点不仅为顾客提供了便捷的服务体验,同时也为企业积累了大量的顾客行为数据。本文旨在…...
MySQL查询优化(三):深度解读 MySQL客户端和服务端协议
如果需要从 MySQL 服务端获得很高的性能,最佳的方式就是花时间研究 MySQL 优化和执行查询的机制。一旦理解了这些,大部分的查询优化是有据可循的,从而使得整个查询优化的过程更有逻辑性。下图展示了 MySQL 执行查询的过程: 客户端…...
pytorch线性回归模型预测房价例子
import torch import torch.nn as nn import torch.optim as optim import numpy as np# 1. 创建线性回归模型类 class LinearRegressionModel(nn.Module):def __init__(self):super(LinearRegressionModel, self).__init__()self.linear nn.Linear(1, 1) # 1个输入特征&…...
UE AController
定义和功能 AController是一种特定于游戏的控制器,在UE框架中用于定义玩家和AI的控制逻辑。AController负责处理玩家输入,并根据这些输入驱动游戏中的角色或其他实体的行为。设计理念 AController设计用于分离控制逻辑与游戏角色,增强游戏设计…...
