【数据结构】关于冒泡排序,选择排序,插入排序,希尔排序,堆排序你到底了解多少???(超详解)

本文主要是介绍【数据结构】关于冒泡排序,选择排序,插入排序,希尔排序,堆排序你到底了解多少???(超详解),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言:

🌟🌟Hello家人们,这期讲解排序算法的原理,希望你能帮到屏幕前的你。

🌈上期博客在这里:http://t.csdnimg.cn/I1Ssq

🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客

目录

📚️1.排序的概念和运用 

1.1排序的概念

1.2排序的运用

1.3常见的排序算法

 📚️2.常见排序算法的实现

2.1插入排序

2.2希尔排序 

2.3选择排序

2.4冒泡排序 

2.5堆排序 

📚️3.排序总结


📚️1.排序的概念和运用 

1.1排序的概念

排序所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作

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

对于稳定性举例: 假如两个人考了一样的分数,那么先交卷的同学成绩因该排在后交卷的同学的前面,这样才符合常理逻辑。

内部排序:数据元素全部放在内存中的排序。
外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。

1.2排序的运用

例如:在通常我们在购物时,总会在界面顶部看到按照价格由低到高,或者由高到低,还有我们平时经常关注的中国大学实力排名等等,又要运用到排序,甚至当我们大打克牌的时候对其进行从小到大的排序,由此可见排序在日常生活中无处不在。

1.3常见的排序算法

这里小编将讲解前五个排序。 

 📚️2.常见排序算法的实现

2.1插入排序

1.插入排序思想:

把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。实际中我们玩扑克牌时,就用了插入排序的想。

2.图解:

3.代码实现:

public static void InsertSort(int array[]){int temp=0;int i;int j;for (j = 1; j < array.length; j++) {temp=array[j];//此时进行大小判断for ( i = j-1; i >=0 ; i--) {if(temp<array[i]){//赋值array[i+1]=array[i];}else {break;}}array[i+1]=temp;}}

这里小编设置了temp表示存储空间,i的值开始都为j-1然后每次递减,与对应的数字进行比较,然后发现对应的位置就将存储的数值,插入其中,j++直到队尾。

 4.插入排序总结

1. 元素集合越接近有序,直接插入排序算法的时间效率越高


2. 时间复杂度:

最坏情况:O(N^2)   (5    4    3    2    1)完全逆序

最好情况:O(N)       (1    2    3    4    5)完全顺序


3. 空间复杂度:O(1),它是一种稳定的排序算法


4. 稳定性:稳定

2.2希尔排序 

1.希尔排序法的思想:

先选定一个整数,把待排序文件中所有记录分成多个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序

2.图解:

其实就是进行分组,然后每组进行插入排序即可,因为最后的分组为1,然而此时的数据已经接近一个有序的排列,所以减少了排序时间。

3.代码实现:

public static void ShellSort(int[] array){int gap= array.length;while (gap>=1){gap/=2;Shell(array,gap);}}public static void Shell(int[] array,int gap){int temp=0;int i;int j;for (j = gap; j < array.length; j++) {temp=array[j];//此时进行大小判断for ( i = j-gap; i >=0 ; i=i-gap) {if(temp<array[i]){//赋值array[i+gap]=array[i];}else {break;}}array[i+gap]=temp;}}

小编在这里设置了两个方法,一个负责进行分组,小编就不在过多赘述,对于另一个方法,这里j的开始为gap是应为分组为gap组,然后每组的第二个元素就为gap下标,i也要减去gap,大家看可以照图来看。

4.希尔排序的总结:

1. 希尔排序是对直接插入排序的优化。


2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。


3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定

4.希尔排序是不稳定的排序

2.3选择排序

1.选择排序基本思想:

每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。

2.图解:

3.代码实现:

public static void SelectSort(int[] array){for (int k = 0; k < array.length-1; k++) {int minIndex=k;for (int j = k+1; j < array.length ; j++) {if(array[j]<array[minIndex]){minIndex=j;}}int temp=array[k];array[k]=array[minIndex];array[minIndex]=temp;}}

注意:每次更新时,minindex下标也要跟着进行更新。

4.选择排序总结:

1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用


2. 时间复杂度:O(N^2)(不管排序情况咋样)


3. 空间复杂度:O(1)


4. 稳定性:不稳定

2.4冒泡排序 

1.冒泡排序思路:

基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,在冒泡排序中通过相邻两个数字的比较,若前面的更小,那么将两者进行交换,然后下标往后移。

2.图解:

3.代码实现:

 public static void BubbleSort(int[] array){for (int i = 0; i <array.length-1 ; i++) {boolean bool=false;for (int j = 0; j < array.length-1-i; j++) {if(array[j]>array[j+1]){swap(j,j+1,array);bool=true;}}if(bool==false){return;}}}

 注意:这里设置了布尔类型,若没有进行交换,则表示这组数据已经有序了,那么此时bool为true,在一次操作后进行判断,为true就直接跳出循环,反之继续进行下一次循环。即对冒泡排序的优化。

4.冒泡排序总结: 

1. 冒泡排序是一种非常容易理解的排序
2. 时间复杂度:O(N^2)
3. 空间复杂度:O(1)
4. 稳定性:稳定

2.5堆排序 

1.堆排序思路:

堆排序(Heapsort) 是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆 来进行选择数据需要注意的是排升序要建大堆,排降序建小堆。

2.图解: 

在这里主要是,先将所给的数据建成一个大根堆,因为堆顶元素肯定是最大的,然后进行与末尾元素进行交换,然后忽视队尾最大元素,再次进行一次向下调整为大根堆,然后又进行与队尾元素交换。

3.代码实现:

public static void HeapSort(int[] array){createBigheap(array);for (int i = array.length-1; i >0 ; i--) {swap(0, i,array);shiftdown(0,array,i-1);}}//创建一个大根堆public static void createBigheap(int[] array){for (int parent = (array.length-2)/2; parent >=0 ; parent--) {shiftdown(parent,array, array.length-1);}}//向下调整public static void shiftdown(int parent,int[] array,int end){int child=parent*2+1;while (child< end){if(array[child]<array[child+1]&&(child+1)<=end){child++;}if(array[parent]<array[child]){int temp=array[parent];array[parent]=array[child];array[child]=temp;}parent=child;child=parent*2+1;}}

这里的向下调整和创建一个大根堆,小编在上一期已经讲解过了,就不再过多赘述。

注意:这里主要是在调用传参的时候,因为要忽略交换后队尾最大元素,所以每次进行向下调整后都要进行边界的调整。

4.堆排序总结:

1. 堆排序使用堆来选数,效率就高了很多。
2. 时间复杂度:O(N*logN)
3. 空间复杂度:O(1)
4. 稳定性:不稳定

📚️3.排序总结

💬💬小编这期主要讲述了对于七大排序的前五个,通过讲解思路,以及画图的方式进行思路分析,以及代码的实现。

对于排序算法来说,主要是抓住每种排序的思想,以及排序的方式,这里可以推荐通过画图的方式进行分析,效果事半功倍~~~

🌅🌅🌅~~~~最后希望与诸君共勉,共同进步!!!


                                💪💪💪以上就是本期内容了, 感兴趣的话,就关注小编吧。

                                                         😊😊  期待你的关注~~~ 

 

这篇关于【数据结构】关于冒泡排序,选择排序,插入排序,希尔排序,堆排序你到底了解多少???(超详解)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1091167

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

如何选择适合孤独症兄妹的学校?

在探索适合孤独症儿童教育的道路上,每一位家长都面临着前所未有的挑战与抉择。当这份责任落在拥有孤独症兄妹的家庭肩上时,选择一所能够同时满足两个孩子特殊需求的学校,更显得尤为关键。本文将探讨如何为这样的家庭做出明智的选择,并介绍星贝育园自闭症儿童寄宿制学校作为一个值得考虑的选项。 理解孤独症儿童的独特性 孤独症,这一复杂的神经发育障碍,影响着儿童的社交互动、沟通能力以及行为模式。对于拥有孤独症兄

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

hdu 1285(拓扑排序)

题意: 给各个队间的胜负关系,让排名次,名词相同按从小到大排。 解析: 拓扑排序是应用于有向无回路图(Direct Acyclic Graph,简称DAG)上的一种排序方式,对一个有向无回路图进行拓扑排序后,所有的顶点形成一个序列,对所有边(u,v),满足u 在v 的前面。该序列说明了顶点表示的事件或状态发生的整体顺序。比较经典的是在工程活动上,某些工程完成后,另一些工程才能继续,此时

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)