数据结构:交换排序

冒泡排序

起泡排序,别名“冒泡排序”,该算法的核心思想是将无序表中的所有记录,通过两两比较关键字,得出升序序列或者降序序列。

算法步骤

  1. 比较相邻的元素。如果第一个元素大于第二个元素,就交换它们。
  2. 对每一对相邻的元素作相同的操作,从开始第一对到末尾的最后一对。
  3. 针对所有的元素重复以上操作,每次出来最后一个

算法理解

例如,对无序表{49,38,65,97,76,13,27,49}进行升序排序的具体实现过程如图 1 所示:

在这里插入图片描述

图 1 第一次起泡

如图 1 所示是对无序表的第一次起泡排序,最终将无序表中的最大值 97 找到并存储在表的最后一个位置。具体实现过程为:

  1. 首先 49 和 38 比较,由于 38<49,所以两者交换位置,即从(1)到(2)的转变;
  2. 然后继续下标为 1 的同下标为 2 的进行比较,由于 49<65,所以不移动位置,(3)中 65 同 97 比较得知,两者也不需要移动位置;
  3. 直至(4),97 同 76 进行比较,76<97,两者交换位置,如(5)所示;
  4. 同样 97>13(5)、97>27(6)、97>49(7),所以经过一次冒泡排序,最终在无序表中找到一个最大值 97,第一次冒泡结束;

由于 97 已经判断为最大值,所以第二次冒泡排序时就需要找出除 97 之外的无序表中的最大值,比较过程和第一次完全相同。

在这里插入图片描述

经过第二次冒泡,最终找到了除 97 之外的又一个最大值 76,比较过程完全一样,这里不再描述。

通过一趟趟的比较,一个个的“最大值”被找到并移动到相应位置,直到检测到表中数据已经有序,或者比较次数等同于表中含有记录的个数,排序结束,这就是起泡排序。

代码实现

#include "iostream"
using namespace std;void swap(int *a, int *b){//交换a和b的位置int temp;temp = *a;*a = *b;*b = temp;
}
int main()
{int array[8] = {49,38,65,97,76,13,27,49};//有多少记录,就需要多少次冒泡,当比较过程,所有记录都按照升序排列时,排序结束for (int i = 0; i < 8; i++){int key=0;//每次开始冒泡前,初始化 key 值为 0//每次起泡从下标为 0 开始,到 8-i 结束for (int j = 0; j+1<8-i; j++){if (array[j] > array[j+1]){key=1;swap(&array[j], &array[j+1]);}}//如果 key 值为 0,表明表中记录排序完成if (key==0) {break;}}for (i = 0; i < 8; i++){cout << array[i] << " ";}return 0;
}

运行结果:

13 27 38 49 49 65 76 97

总结

使用起泡排序算法,其时间复杂度同实际表中数据的无序程度有关。若表中记录本身为正序存放,则整个排序过程只需进行 n-1(n 为表中记录的个数)次比较,且不需要移动记录;若表中记录为逆序存放(最坏的情况),则需要 n-1趟排序,进行 n(n-1)/2 次比较和数据的移动。所以该算法的时间复杂度为O(n2)。

快速排序

快速排序本质上是可以说是冒泡排序基础上的递归分治法,它也是分治算法在排序算法上的一种经典应用。

算法思想

快速排序是通过多次比较和交换来实现有序的。在一次排序中把将要排序的元素分成两个独立的子数组,其中一个子数组的所有元素全大于另一个组数组的所有元素,然后继续递归排序这两部分。

算法思想步骤:

  1. 从序列中挑出一个元素,称之为边界或者基准
  2. 重新排序数列,所有元素比基准值小的放在基准前面,所有元素比基准值大的放在基准后面(相同的数可以放在任意一边)。这个操作结束后,该基准就处于序列的中间位置,这个操作称之为分区操作
  3. 递归吧小于基准元素的组数组和大于基准元素的子数组排序

算法理解

在这里插入图片描述

代码实现

#include "iostream"
using namespace std;#define MAX 9
//单个记录的结构体
typedef struct {int key;
}SqNote;
//记录表的结构体
typedef struct {SqNote r[MAX];int length;
}SqList;
//此方法中,存储记录的数组中,下标为 0 的位置时空着的,不放任何记录,记录从下标为 1 处开始依次存放
int Partition(SqList *L,int low,int high){L->r[0]=L->r[low];int pivotkey=L->r[low].key;//直到两指针相遇,程序结束while (low<high) {//high指针左移,直至遇到比pivotkey值小的记录,指针停止移动while (low<high && L->r[high].key>=pivotkey) {high--;}//直接将high指向的小于支点的记录移动到low指针的位置。L->r[low]=L->r[high];//low 指针右移,直至遇到比pivotkey值大的记录,指针停止移动while (low<high && L->r[low].key<=pivotkey) {low++;}//直接将low指向的大于支点的记录移动到high指针的位置L->r[high]=L->r[low];}//将支点添加到准确的位置L->r[low]=L->r[0];return low;
}
void QSort(SqList *L,int low,int high){if (low<high) {//找到支点的位置int pivotloc=Partition(L, low, high);//对支点左侧的子表进行排序QSort(L, low, pivotloc-1);//对支点右侧的子表进行排序QSort(L, pivotloc+1, high);}
}
void QuickSort(SqList *L){QSort(L, 1,L->length);
}
int main() {SqList *L = new SqList;L->length=8;L->r[1].key=49;L->r[2].key=38;L->r[3].key=65;L->r[4].key=97;L->r[5].key=76;L->r[6].key=13;L->r[7].key=27;L->r[8].key=49;QuickSort(L);for (int i=1; i<=L->length; i++) {cout << L->r[i].key << " ";}return 0;
}

运行结果:

13 27 38 49 49 65 76 97

总结

快速排序算法的时间复杂度为O(nlogn),是所有时间复杂度相同的排序方法中性能最好的排序算法。

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

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

相关文章

关于MPU6050的VLOGIC引脚作用

关键字&#xff1a;MPU6X0X、 MPU6050、数字逻辑电平、VLOGIC 框图&#xff1a; 一、VLOGIC引脚作用? VLOGIC引脚主要用于设置为I2C供电引脚&#xff0c;以保证正确的I2C通信。 The bias and LDO section generates the internal supply and the reference voltages and cu…

编译iOS系统可用的FFmpeg

在进行编译之前&#xff0c;需要做一些准备工作安装必备文件&#xff1a; 1 安装 gas-preprocessor FFmpeg-iOS-build-script 自动编译脚本需要使用到 gas-preprocessor . 执行 sudo git clone https://github.com/bigsen/gas-preprocessor.git /usr/local/bin/gas sudo c…

Docker 方式 部署 vue 项目 (docker + vue + nginx)

1.安装好 nginx 。 2. 把 vue 项目的源码克隆到确定目录下。用 git 管理&#xff0c;所以直接 git clone 到既定目录就行了。 如我的目录是&#xff1a;/root/jiangyu/projects/gentle_vue/gentle_vue_code 。 3. 项目打包&#xff1a; npm run build 复制 会自动生成 dist…

若依框架权限管理的RBAC模型介绍

若依框架的权限管理功能是基于【RBAC】来实现的&#xff0c;即&#xff1a;系统中所有的权限&#xff0c;都是基于角色来控制的。框架对权限的控制&#xff0c;不仅支持菜单的功能&#xff0c;还支持菜单中的每一个按钮的权限控制   RBAC&#xff08;基于角色的访问控制&#…

Maven介绍,部署在eclipse中

目录 一.Maven介绍 1&#xff0c;什么是maven&#xff1f; 2. 为什么maven会在企业中大量使用&#xff1f; 3.没有使用maven的前后区别? 4.maven在Java开发中的实际效果图 二.maven部署在eclipse中 1.下载maven在其官方网址下载&#xff08;当然实际下载也要根据个人的…

数据结构-带头双向循环链表的实现

前言 带头双向循环链表是一种重要的数据结构&#xff0c;它的结构是很完美的&#xff0c;它弥补了单链表的许多不足&#xff0c;让我们一起来了解一下它是如何实现的吧&#xff01; 1.节点的结构 它的节点中存储着数据和两个指针&#xff0c;一个指针_prev用来记录前一个节点…

如何通知学生分班结果?这个代码源轻松搞定

传统通知学生分班结果的方式相对来说比较繁琐&#xff0c;同时也存在出错的风险。首先&#xff0c;传统方式通常是通过纸质通知单的形式将分班结果发放给学生。这就需要学校花费一定的人力和物力来打印、分发通知单&#xff0c;而且还需要确保通知单能够准确地送到每个学生手中…

OpenAI允许网站阻止其网络爬虫;谷歌推出类似Grammarly的语法检查功能

&#x1f989; AI新闻 &#x1f680; OpenAI推出新功能&#xff0c;允许网站阻止其网络爬虫抓取数据训练GPT模型 摘要&#xff1a;OpenAI最近推出了一个新功能&#xff0c;允许网站阻止其网络爬虫从其网站上抓取数据训练GPT模型。该功能通过在网站的Robots.txt文件中禁止GPTB…

图像的镜像变换之c++实现(qt + 不调包)

1.基本原理 1.水平镜像变化 设图像的宽度为width&#xff0c;则水平镜像变化的映射关系如下&#xff1a; 2.垂直镜像变化 设图像的宽度为height&#xff0c;则垂直镜像变化的映射关系如下&#xff1a; 2.代码实现&#xff08;代码是我以前自学图像处理时写的&#xff0c;代码很…

Nature子刊 |肠道宏病毒组揭示百岁老人长寿秘诀

发表期刊&#xff1a;nature microbiology 发表时间&#xff1a;2023 影响因子&#xff1a;28.3 DOI: 10.1038/s41564-023-01370-6 研究背景 衰老是一种不可逆转的自然过程&#xff0c;随着年龄的增长&#xff0c;机体诸多方面出现功能性下降&#xff0c;与衰老相关的疾病&a…

设计模式之三大类

目录 设计模式分类 1.创建型模式(Creational Patters) 2.结构型模式(Structural Patterns) 3.行为型模式(Behavioral Patterns) 3.1命令模式(The Command Pattern) 2.1适配器模式 2.1.1Object and Class Adapters 设计模式分类 1.创建型模式(Creational Patters) Fato…

手撕数据结构之栈+例题

目录 一、栈的概念及结构 二、栈的头文件及基本框架 三、接口实现 1、对栈的初始化 2、栈的销毁 3、入栈操作 4、出栈操作 5、判断栈是否为空 6、返回栈顶元素 7、遍历栈 四、有效的括号 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 思路&#xff…