数据结构:冒泡排序,选择排序,插入排序,希尔排序的实现分析

✨✨小新课堂开课了,欢迎欢迎~✨✨

🎈🎈养成好习惯,先赞后看哦~🎈🎈

所属专栏:数据结构与算法

小新的主页:编程版小新-CSDN博客

 1.冒泡排序

1.1算法思想

冒泡排序的基本思想就是,遍历原数组的元素,比较相邻的两个元素,如果这两个元素的顺序不对,就是把这两个元素交换,直到都不需要交换的时候,排序结束。

1.2具体步骤

比较相邻的两个元素,把大的(小的)往后换,就这样重复此步骤,每遍历完数组一次,就能将最大的(最小的)元素放在最后。重复遍历该数组,直至都不需要交换的时候,排序就结束了。

1.3动图演示

24年-05月27日--排序/动图/冒泡排序.gif

1.4代码实现

void Swap(int*a,int*b)
{int tmp = *a;*a = *b;*b = tmp;
}
//冒泡排序
void BubbleSort(int* arr, int len)
{for (int i = 0; i < len - 1; i++)//比较次数{for (int j = 0; j < len-1-i; j++)//单趟比较{if (arr[j] > arr[j + 1]){Swap(&arr[j], &arr[j + 1]);}}}
}

有的时候不用遍历数组len次,排序就已经排好了,我们知道遍历完数组一次后,如果不存在交换,那就不用再继续比较了。此时排序已经排好了。

优化:

void Swap(int*a,int*b)
{int tmp = *a;*a = *b;*b = tmp;
}
//冒泡排序
void BubbleSort(int* arr, int len)
{int flag = 0;for (int i = 0; i < len - 1; i++)//比较次数{for (int j = 0; j < len-1-i; j++)//单趟比较{if (arr[j] > arr[j + 1]){Swap(&arr[j], &arr[j + 1]);flag = 1;}}if(flag ==0)//未发生交换,排序已经完成break;}
}

1.5复杂度分析

时间复杂度:这里很容易就能看出来是O(N^2)。以最坏的情况来看,n-1+n-2+n-3+……+2+1=n*(n-1)/2。

空间复杂度: 因为没有额外的开空间,所以空间复杂度为O(1)。

1.6稳定性分析

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

简而言之,相同值相对位置不变称之为稳定。

 冒泡排序是相邻位置的元素比较,决定交不交换,一样的元素,在排序过程中相对位置不会发生变化,因此冒泡排序是稳定的

2.选择排序

2.1算法思想

遍历原数组,找出最小或者最大的那个元素,与起始位置或则末尾的元素交换,每遍历完一次,起始位置向后移(末尾的位置往前移),当起始位置移到最后一个位置时(末尾位置移到数组的第一个元素的位置时),排序结束。

2.2具体步骤

遍历数组,找到最大或者最小的元素,与起始位置交换。

从剩余的元素中找继续找最大或最小的元素,排到已排序序列的末尾。

以此类推,直到所有的元素都排列完毕。

2.3动图演示

2.4代码实现

基于动态演示实现的代码:

void SelectSort(int* arr, int len)//选择排序
{for (int i = 0; i < len - 1; i++)//起始位置{int mini = i;for (int j = i + 1; j < len; j++)//寻找最小元素{if (arr[j] < arr[mini]){mini = j;}}swap(&arr[mini], &arr[i]);}
}

上面的代码效率比较低,我们在遍历一遍数组的时候,可以找到该数组中最大和最小的元素,让最大的元素与end交换,最小的元素与begin交换,不断的这样缩小区间,完成排序。

这里要注意的是,我们在交换的时候,可能会改变最大或最小元素的位置 。

//选择排序void Swap(int*a,int*b)
{int tmp = *a;*a = *b;*b = tmp;
}void SelectSort(int* arr, int len)
{int begin = 0;int end = len - 1;while (begin < end){int mini = begin;int maxi = begin;for (int i = begin + 1; i <=end; i++){//遍历一遍找最大和最小if (arr[i] > arr[maxi]){maxi = i;}if (arr[i] < arr[mini]){mini = i;}}Swap(&arr[begin], &arr[mini]);if (maxi == begin)//如果begin和maxi重合,就要对maxi更正{maxi = mini;}Swap(&arr[end], &arr[maxi]);begin++;end--;}
}

2.5复杂度分析

时间复杂度:优没优化,算时间复杂度的时候都是等差数列,时间复杂度为O(N^2)。

空间复杂度:没有额外开辟空间,因此空间复杂度为O(N)。

2.6稳定性分析

3.插入排序

3.1算法思想

把待排元素逐一与已排序的部分元素进行比较,把它插入到已排序序列中的适当位置,直到把元素全部插入完毕。

3.2具体步骤

把第一个元素看成有序序列,从第二个元素开始,将该元素与前面已排好序的元素比较,如果该元素比较小,就将前面的元素依次往后移动一位,将该元素插入到腾出的位置上。

重复上面的插入过程,直至整个序列都被排序完成。

3.3动图演示

3.4代码实现

// 插入排序
void InsertSort(int* a, int n)
{//【0-end】有序,将end+1的值插入到区间内,形成新的区间for (int i = 0; i < n - 1; i++){int end = i;int tmp = a[end + 1];while (end >= 0){if (a[end] > tmp){a[end + 1] = a[end];//往后移end--;}else{break;//找到合适的位置了//也有可能合适的位置就是数组的起始位置,没有进break,此时end为-1越界,在// end+1的位置插入,就是把该元素插入到起始位置}}a[end + 1] = tmp;//在腾出来的位置插入该元素}}

3.5复杂度分析

时间复杂度:以最坏的情况,逆序来算,移动的次数是等差数列的前n-1项和,O(N^2)。

空间复杂度:没有额外开辟空间,空间复杂度为O(1)。

3.6稳定性分析

插入排序不会改变相同元素的相对位置,在前面的和在后面的那个在插入到腾出的位置后,还是一前一后。因此插入排序稳定

4.希尔排序

4.1算法思想

希尔排序是对插入排序的改进。它先将整个待排的序列分割成若干个子序列,对每一个子序列分别进行插入排序,然后不断缩小缩小子序列的间隔,重复这个过程直至间隔为1 时进行一次完整的插入排序。

4.2具体步骤

希尔排序分为两步:1.预排序(使数组接近有序) 2.插入排序

选取一个gap,间隔gap个数据为一组,把整个数组进行分组,一共gap组。

以gap为基准,对其进行插入排序。

不断缩小gap,直至gap为1,进行一次完整的插入排序。

gap>1时是在进行预排序,gap==1是在进行直接插入排序。          

4.3动图演示

4.4代码实现

// 希尔排序
//希尔排序分为两步:第一步是预排序(使其接近有序),第二步是进行插入排序
void ShellSort(int* a, int n)
{int gap = n;//gap代表每间隔gap个为一组即一共分成gap组while (gap > 1){//gap>1是进行预排序//gap==1是在进行插入排序gap = gap / 3 + 1;//+1是保证最后一组gap一定为1,for (int i = 0; i < n - gap; i++){int end = i;int tmp = a[end + gap];//i之所以小于n-gap;是防止这里越界while (end >= 0){if (a[end] > tmp){a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = tmp;}}
}

4.5复杂度分析

时间复杂度:希尔排序的时间复杂度可以直接记,因为比较难算。O(N^1.3)

空间复杂度:没有额外开辟空间,空间复杂度为O(1)。

4.6稳定性分析

在排序过程中,可能相同数据分到不同的组,这个无法控制,因此希尔排序不稳定

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

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

相关文章

由浅入深,走进深度学习(4)

各位小伙伴大家好&#xff0c;这期内容是深度学习基础的一个进阶&#xff0c;也可以说是夯实一下很多细节内容 个人感受&#xff1a;动手敲一遍&#xff0c;带着思考&#xff0c;会有不一样的感受&#xff01;&#xff01;&#xff01; 代码是比较多的&#xff0c;有很多内容…

全局变量和局部变量

全局变量未初始化&#xff0c;则它的值为0&#xff1b; 局部变量未初始化&#xff0c;则它的值为随机值&#xff1b; 局部变量的作用域是变量所在的局部范围; 全局变量的作用域是整个工程; 生命周期&#xff1a; 变量的生命周期指的是变量从创建到销毁的整个阶段。 局部变量的生…

react实现路由拦截器

1. 路由拦截的概念 路由拦截&#xff1a;在用户导航到某个路由之前&#xff0c;通过某种逻辑来拦截、检查或修改导航行为。它可以用于实现权限控制、身份验证、页面加载前的准备工作等场景。 2. React Router中的路由拦截实现 2.1 使用<Route>组件的render属性 在Rea…

每天一个项目管理概念之关键路径

在项目管理中&#xff0c;关键路径分析&#xff08;Critical Path Method, CPM&#xff09;是计划和控制项目时间表的重要工具。关键路径是项目网络图中从开始到结束的最长路径&#xff0c;它确定了完成整个项目所需的最短时间。任何关键路径上的任务延误都将直接导致整个项目延…

mysql插入blob或longblob的字符串

mysql字段格式是blob的时候&#xff0c;直接插入字符串会异常 insert table (str),values (aaaa)会异常 需要将字符串转为0x格式的16进制字符串才行 aaaa转换之后为61616161 insert table (str),values (0x61616161)java将字符串转16进制字符串 "0x"DatatypeConver…

使用zdppy结合onlyoffice开发第一个网页文档应用

docserver环境搭建 禁用JWT 加载镜像&#xff1a; docker load -i docserver:7运行容器&#xff1a; docker run -itd -p 8080:80 --name docserver -e JWT_ENABLEDfalse --restartalways onlyoffice/documentserver:7.3.2docker run -itd -p 8080:80 --name docserver -…

字节跳动:从梦想之芽到参天大树

字节跳动掌舵人&#xff1a;张一鸣 2012年&#xff1a;梦想的起点&#xff1a;在一个阳光明媚的早晨&#xff0c;北京的一座普通公寓里&#xff0c;一位名叫张一鸣的年轻人坐在电脑前&#xff0c;眼中闪烁着坚定的光芒。他的心中有一个梦想——通过技术改变世界&#xff0c;让…

如何使用Java实现高效的多线程编程

如何使用Java实现高效的多线程编程 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 引言 在当今软件开发领域中&#xff0c;多线程编程是一项关键技能。它能够…

嵌入式实验---实验六 I2C传输实验

一、实验目的 1、掌握STM32F103I2C传输程序设计流程&#xff1b; 2、熟悉STM32固件库的基本使用。 二、实验原理 1、本案例利用I/O端口通过KEY01按键来控制STM32F103R6向24C02写入“hello”&#xff0c;通过另外一个按键KEY02来控制STM32F103R6从24C02读取“hello”&#x…

又一个前后端分离的整合了OpenAI大模型的高并发、高性能和可扩展的项目完结了,写到简历上,嘎嘎强!

大家好&#xff0c;我是冰河~~ 经过四个多月的坚持&#xff0c;《分布式IM即时通讯系统》终于完结了&#xff0c;也感谢大家这四个多月以来的坚持和陪伴&#xff0c;也相信大家在《分布式IM即时通讯系统》专栏中&#xff0c;学到了不少知识和技术。接下来&#xff0c;我们就一…

[C++][设计模式]介绍

目录 1.设计模式1.何为设计模式&#xff1f;2.深入理解面向对象3.软件设计的目标4.三大模式及其特点5.设计模式分类 2.面向对象设计原则1.为什么要面向对象2.重新认识面向对象3.面向对象设计原则4.C对象模型 3.重构1. 重构获得模式(Refactoring to Patterns)2.重构关键技法 4.代…

代码随想录leetcode200题之图论

目录 1 介绍2 训练3 参考 1 介绍 本博客用来记录代码随想录leetcode200题之图论相关题目。 2 训练 题目1&#xff1a;98. 所有可达路径 解题思路&#xff1a;有向图&#xff0c;dfs(fa, node)。 C代码如下&#xff0c; #include <bits/stdc.h>using namespace std;…

归并排序代码

主程序 int main(int argc, char const *argv[]) {int arr[] {9,5,2,7};int n sizeof(arr)/siezof(arr[0]);print_arr(arr,n);//打印数组merge_sort(arr, n);//分类数组print_arr(arr,n);//打印数组return 0; } 归并排序入口 //归并排序入口 void merge_sort(int arr[], in…

一文带你了解集装箱箱号识别原理,OCR识别及深度学习

如果要想知道集装箱箱号识别原理&#xff0c;首先需要知道什么是集装箱号&#xff08;装运出口货物的集装箱箱号&#xff09;标准集装箱箱号由11位编码组成包括三个部分&#xff1a; 第一部分由4位英文字母组成。前三位代码主要说明箱主、经营人&#xff0c;第四位代码说明集装…

【Oracle】实验二 体系结构、存储结构与各类参数

【实验目的】 理解Oracle体系结构了解初始化参数文件以及初始化参数的含义掌握查看三类数据字典视图和动态性能视图的方法 【实验内容】 如何查看初始化参数&#xff1f;有哪几种方法&#xff1f;初始化参数文件有几种&#xff1f;默认的保存位置在哪里&#xff1f;在SQL*Pl…

【开发】内网穿透ztncui搭建私有节点

文章目录 写在前面一键部署ztnuci记录后续 写在前面 前面搭建moon节点转发的确会降低延迟&#xff0c;但是总有出现moon节点解析不成功的例子&#xff0c;于是疯狂寻找答案是为什么&#xff1f;终于在知乎上找到这样一个答案。 一键部署ztnuci 参考这篇很完善的教程和贴心的…

AI味太重怎么办?1个超简单的方法就能解决

我们知道随着GPT技术的迅速发展&#xff0c;解决了我们大部分写作的难题。但是很多小伙伴想必都会遇到同样的问题&#xff0c;就是写出来的文章太正式-我们叫这“AI味”。 这AI味让人感觉内容虽然条理清楚&#xff0c;但就是缺了点人情味&#xff0c;读起来不够亲切。 其实&a…

基于YOLOv5的口罩佩戴检测系统的设计与实现(PyQT页面+YOLOv5模型+数据集)

简介 在各种工作环境和公共场所,确保人们正确佩戴口罩对个人防护和公共卫生至关重要,尤其是在医疗设施、制造业车间和拥挤的公共交通中。为了满足这一需求,我们开发了一种基于YOLOv5目标检测模型的口罩佩戴检测系统。本项目不仅实现了高精度的口罩佩戴检测,还设计了一个可…

【计算机网络仿真】b站湖科大教书匠思科Packet Tracer——实验6 生成树协议STP的功能

一、实验目的 1.验证以太网交换机生成树协议的功能&#xff1b; 2.理解网络环路对网络的负面效应&#xff1b; 3.理解生成树协议的作用。 二、实验要求 1.使用Cisco Packet Tracer仿真平台&#xff1b; 2.观看B站湖科大教书匠仿真实验视频&#xff0c;完成对应实验。 三、实…

Android assets资源目录

目录 前言一、读取assets下的文件内容二、拷贝assets文件三、AssetManager 前言 Android 中常用的资源分为两种&#xff1a; res下可编译的资源文件assets文件夹下面的原生资源文件 第一种是res下可编译的资源文件&#xff0c;这些资源文件经过编译后会生成一个R.java文件&a…