排序算法漫游:从冒泡到堆排的底层逻辑与性能厮杀

各位看官早安午安晚安呀

如果您觉得这篇文章对您有帮助的话

欢迎您一键三连,小编尽全力做到更好
欢迎您分享给更多人哦

今天我们来学习七大排序算法

一:直接插入排序

直接插入排序是一种简单的插入排序法,其基本思想是:
把待排序的 逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到 一个新的有序序列 。实际中我们玩扑克牌时,就用了插入排序的思想。
  /*** 时间复杂度:最好:O(n):本身就是有序的{1,2,3,4,5}** 最坏 O(n^2):{5,4,3,2,1}** 空间复杂度:O(1);(没有额外的申请空间)** 稳定性:稳定的排序** @param array*/public static void insertSort(int[] array){for (int i = 1; i < array.length; i++) { //第一个元素就不用比较了,直接看第二个元素能不能插进去,i:每次要插入的元素的下标int j = i - 1;int tmp = array[i];for (; j >= 0 ; j--) {if(array[j] > tmp){ //加等号就不稳定了array[j + 1] = array[j];//你往前移动,让tmp插进去}else{break;}}array[j +1] = tmp;//一个是循环里刚好(array[i] < tmp):array[j+1] = tmp;}}

直接插入排序的特性总结:
1. 元素集合越接近有序,直接插入排序算法的时间效率越高
2. 时间复杂度: O(N^2)
3. 空间复杂度: O(1) ,它是一种稳定的排序算法
4. 稳定性:稳定

二:希尔排序(缩小增量排序

希尔排序法又称缩小增量法。(譬如一个8个元素的数组(先分成4组),我们第一次先让第一个元素和第五个元素比较,看看能不能插入,第二个和第六个元素比较,以此类推;第二次分成两组,第一个和第三个比较,然后第五个元素看看能不能插入第一个和第三个元素里面…………依次类推)
    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){for (int i = gap ; i < array.length; i++) {int tmp = array[i];int j = i - gap;for (; j >= 0 ; j-= gap) {if(array[j] > tmp){array[j + gap] = array[j];}else{break;}}array[j +gap] = tmp;}}

关于希尔排序的时间复杂度:一般认为是并且是不稳定的

三: 选择排序(1)


3.1: 选择排序(1)

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

/*** 时间复杂度:O(n^2)(不管怎么样都是)(n-1)+……+2+1* 空间复杂度:O(1)* 稳定性:不稳定*  堆排序* @param array*/public static void chanceSort(int[] array){//{ 9,3,5,6,2,4}//首先就是第一个数字和后面的所有数字进行比较,找到一个最小的数字放在最前面//譬如第一遍首先最小的是9,然后变成3,最后变成了2的下标
//第二次从第二个元素开始往后找、找最小的元素for (int i = 0; i < array.length; i++) {int minIndex = i;for (int j = i +1; j < array.length; j++) {if(array[j] < array[minIndex]){minIndex = j;}}swap(array , minIndex,i);}}

直接选择排序的特性总结
1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
2. 时间复杂度: O(N^2)(不管怎么样都是O(n))
3. 空间复杂度: O(1)
4. 稳定性:不稳定

3.2: 选择排序(2)

public static void chanceSort2(int[] array){//我的评价是不如上面那个方法,因为你俩的的时间复杂度完全一样//{ 9,3,5,6,2,4}int left = 0;int right = array.length-1;while(left < right){ //你俩相遇了就不用比了int maxIndex = left;int minIndex = left;//这个i = left +1(从第二个元素和第一个元素进行比较)for (int i = left + 1; i <= right;i++) {//right = array.lengthif(array[i] < array[minIndex]){minIndex = i;}//找到最大的元素放在最后if(array[i] > array[maxIndex]){maxIndex = i;}}swap(array , minIndex,left);//最大值刚好在最小值的位置,所以说最大值已经被交换到了“现在的minIndex的位置”if(maxIndex == left){maxIndex = minIndex;}swap(array,maxIndex,right);left++;right--;}}

四:堆排序(Heapsort)

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

public static void heapSort(int[] array){createBigHeap(array);//创建一个大根堆int end = array.length -1;//为什么要一开始end = array.length-1呢因为,我向下调整的时候不需要调整最后一个元素(最大的一个元素)while(end != 0) {swap(array, 0, end);//交换是肯定要交换最后一个元素啦shiftDown(0, array,end);//这里传的是array.length -1(不需要调整最后那个大的元素)end --;}}public static void createBigHeap(int []array){for (int parent = (array.length-1 -1)/2; parent >= 0; parent--) {shiftDown(parent,array,array.length);//这里减一}}private static void shiftDown(int parent, int []array,int end) {int child = parent *2 +1;while(child < end){ //我创建大根堆的时候传过来的end =array.length//但是我堆排序的时候每次不需要调整最后一个元素了,所以传过来的是array.length-1if(child +1 < end && array[child] < array[child +1]){ //更改child++;}if(array[child] > array[parent]){swap(array,parent,child);parent = child;child = parent *2 +1;}else{break;}}}
直接选择排序的特性总结
1. 堆排序使用堆来选数,效率就高了很多。
2. 时间复杂度: O(N*logN)
3. 空间复杂度: O(1)
4. 稳定性:不稳定

五:交换排序

 /*** 2. 时间复杂度:O(N^2),经过改良之后最小为O(n)(完全有序,走一遍就break了)* 3. 空间复杂度:O(1)* 4. 稳定性:稳定* @param array*/public static void bubbleSort(int[] array){for (int i = 0; i < array.length; i++) {boolean flag = false;for (int j = 0; j < array.length -1 -i; j++) {if(array[j] > array[j+1]){swap(array,j,j+1);flag = true;}}if(flag == false){break;}}}

六:快速排序

快速排序是 Hoare 1962 年提出的一种二叉树结构的交换排序方法,其基本思想为: 任取待排序元素序列中的某元 素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值右子序列中所有 元素均大于基准值然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止 (递归)
public static void quickSort(int[] array){quick(array,0,array.length -1);}public static void quick(int[] array,int start,int end) {if(start >= end){return;}int pivot = quickSortSmall(array,start,end);quick(array,start,pivot- 1);//这里一定要注意开始的边界一定要是start,不能是0
//你要想想如果,现在正在递归我右边的左边(这个起始其实应该是pivot+1)quick(array,pivot +1,end);}public static int  quickSortSmall(int[] array, int left, int right){int location = left;//保留我原来的最左边的下标int key = array[left];while(left < right){while(left < right && array[right] >= key){ //大循环里面的小循环一定要注意边界right--;}while(left < right && array[left] <= key){//都要加等号,不然可能走不动呀left++;}swap(array,left,right);}swap(array , location,left);让相遇点下标的值和我的起始值进行交换
//每次相遇的时候的值都小于等于我的起始值,
//情况一:right动到left(由于right先动的,left还处于上一次交换完的<key
//情况二:left动到了right,想都不用想,right先动到了小于key的值
//情况三:一开始left就没动过,right一下就到了left(相当于这个树没有左子树)return left;}

Test:测试七大排序算法

(冒泡除外)

import java.util.Arrays;
import java.util.Random;public class Test {public static void orderArray(int[] array){for (int i = 0; i < array.length; i++) {array[i] = i;}}public static void notOrderArray(int[] array){for (int i = 0; i < array.length; i++) {array[i] = array.length - i;}}public static void randomArray(int[] array){Random random = new Random();for (int i = 0; i < array.length; i++) {array[i] = random.nextInt(100000);}}public static void testInsertSort(int[] array){//这样不对 :int []tmpArray = array;//要copy,不然你给我排序了,后面的就是有序了呀int[] tmpArray = Arrays.copyOf(array,array.length);//开始和结束的时间long startTime = System.currentTimeMillis();Sort.insertSort(tmpArray);long endTime = System.currentTimeMillis();//这里一定要加括号呀,不然就相当于你一个字符串减去一个数字,肯定报错System.out.println("插序消耗时间:" + (endTime - startTime));}public static void main2(String[] args) {int[] array = new int[10000];//orderArray(array);notOrderArray(array);//randomArray(array);testInsertSort(array);testShellSort(array);testQuickSort(array);testHeapSort(array);}public static void main(String[] args) {//int[] array = new int[100000];int []array = {4,5,3,8,2};Sort.bubbleSort(array);//Sort.shellSort(array);//Sort.chanceSort2(array);//Sort.heapSort(array);//Sort.quickSort(array);System.out.println(Arrays.toString(array));}
}

上述就是排序算法漫游:从冒泡到堆排的底层逻辑与性能厮杀

的全部内容了,能看到这里相信您一定对小编的文章有了一定的认可。

有什么问题欢迎各位大佬指出
欢迎各位大佬评论区留言修正~~

您的支持就是我最大的动力​​​!!!!

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

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

相关文章

【VBA】WPS/PPT设置标题字体

通过VBA&#xff0c;配合左上角的快速访问工具栏&#xff0c;实现自动化调整 选中文本框的 字体位置、大小、颜色。 配合quicker更加便捷 Sub DisableAutoWrapAndFormat()Dim shp As Shape 检查是否选中了一个形状&#xff08;文本框&#xff09;If ActiveWindow.Selection.Typ…

大语言模型从理论到实践(第二版)-学习笔记(绪论)

大语言模型的基本概念 1.理解语言是人工智能算法获取知识的前提 2.语言模型的目标就是对自然语言的概率分布建模 3.词汇表 V 上的语言模型&#xff0c;由函数 P(w1w2 wm) 表示&#xff0c;可以形式化地构建为词序列 w1w2 wm 的概率分布&#xff0c;表示词序列 w1w2 wm…

Qt常用控件之 纵向列表QListWidget

纵向列表QListWidget QListWidget 是一个纵向列表控件。 QListWidget属性 属性说明currentRow当前被选中的是第几行。count一共有多少行。sortingEnabled是否允许排序。isWrapping是否允许换行。itemAlignment元素的对齐方式。selectRectVisible被选中的元素矩形是否可见。s…

使用 Apache POI 实现 Excel 单元格合并

在日常工作中&#xff0c;Excel 是一个不可或缺的工具&#xff0c;尤其是在处理大量数据时。为了提升数据的可读性和美观性&#xff0c;我们经常需要对 Excel 中的单元格进行合并操作。本文将介绍如何使用 Apache POI 库在 Java 中实现 Excel 单元格的合并&#xff0c;并提供一…

leetcode日记(84)交错字符串

很明显的动态规划&#xff0c;就是怎么用想了一段时间。&#xff08;开始还怀疑过是不是双指针&#xff0c;发现不行&#xff0c;因为会出现s3的下一个字符同时能够匹配到两个字符串字符的情况&#xff09; 然后就是构建数组dp[101][101]&#xff0c;数组代表前x个s1字符和前y…

【Linux———信号精讲】

你是怎么做到的&#xff0c;给了她想要的爱............................................................................................ 文章目录 前言 一、【信号入门】 1.1、【生活角度的信号】 1.2、【ctrl c与z】 1.3、【信号的发送与记录】 1.4、【信号处理常见方式…

【原创】springboot+vue核酸检测管理系统设计与实现

个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;源码获取&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交给天意。 研究…

Qt6.8.2创建WebAssmebly项目使用FFmpeg资源

Qt6新出了WebAssmebly功能&#xff0c;可以将C写的软件到浏览器中运行&#xff0c;最近一段时间正在研究这方便内容&#xff0c;普通的控件响应都能实现&#xff0c;今天主要为大家分享如何将FFmpeg中的功能应用到浏览器中。 开发环境&#xff1a;window11&#xff0c;Qt6.8.2…

LeetCode 解题思路 12(Hot 100)

解题思路&#xff1a; 定义三个指针&#xff1a; prev&#xff08;前驱节点&#xff09;、current&#xff08;当前节点&#xff09;、nextNode&#xff08;临时保存下一个节点&#xff09;遍历链表&#xff1a; 每次将 current.next 指向 prev&#xff0c;移动指针直到 curre…

用数据唤醒深度好眠,时序数据库 TDengine 助力安提思脑科学研究

在智能医疗与脑科学快速发展的今天&#xff0c;高效的数据处理能力已成为突破创新的关键。安提思专注于睡眠监测与神经调控&#xff0c;基于人工智能和边缘计算&#xff0c;实现从生理体征监测、智能干预到效果评估的闭环。面对海量生理数据的存储与实时计算需求&#xff0c;安…

玩转若依二次开发之若依框架Springboot+Vue3

目录 一、使用&#xff08;非重点&#xff09; 0.准备工作 1.下载git地址 2.配置信息 3.系统启动 4.DIY主题样式和文案 二、使用&#xff08;重点&#xff09; 1.单表生成Java和vue3代码 1.1.创建用户表 1.2.生成Java和vue3代码 1.3.把生成代码复制到项目中 1.4.重…

llamafactory大模型微调教程(周易大模型案例)

1.环境说明 操作系统&#xff1a;ubuntu 20 基础模型&#xff1a;Qwen2.5-1.5B-Instruct 工具&#xff1a;llamafactory GPU&#xff1a;四张4090 2、环境部署 2.1 下载基础模型 # 1、下载 modelscope pip install modelscope#2、模型下载 cd /data/ cat >> download…

06 HarmonyOS Next性能优化之LazyForEach 列表渲染基础与实现详解 (一)

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; 目录 一、代码结构概览二、详细代码解析1. 数据源管理实现2. 数据结构定义3. 优化的列表项组件4. 主列表组件实现 一、代码结构概览 本文将详细解…

【Linux】线程同步与互斥

线程同步与互斥 一.线程互斥1.互斥相关概念2.互斥锁 Mutex3.互斥锁接口4.互斥锁实现原理5.互斥锁封装 二.线程同步1.同步相关概念2.条件变量 Condition Variable3.条件变量接口4.条件变量封装5.信号量 Semaphore6.信号量接口7.信号量封装 三.生产者 - 消费者模型1.基于 Blockin…

基于大数据的电影情感分析推荐系统

【大数据】基于大数据的电影情感分析推荐系统&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 本系统通过结合Flask框架、Vue前端、LSTM情感分析算法以及pyecharts和numpy、pandas等技术&#x…

网络安全配置截图 网络安全i

网络安全概念及规范 1.网络安全定义 网络安全的概述和发展历史 网络安全 广义的网络安全&#xff1a;Cyber Security&#xff08;网络空间安全&#xff09; 网络空间有独立且相互依存的信息基础设施和网络组成&#xff0c;包括互联网、电信网、计算机系统、嵌入式处理器和控…

测试用例详解

一、通用测试用例八要素   1、用例编号&#xff1b;    2、测试项目&#xff1b;   3、测试标题&#xff1b; 4、重要级别&#xff1b;    5、预置条件&#xff1b;    6、测试输入&#xff1b;    7、操作步骤&#xff1b;    8、预期输出 二、具体分析通…

mybatis映射文件相关的知识点总结

mybatis映射文件相关的知识点总结 mybatis官网地址 英文版&#xff1a;https://mybatis.org/mybatis-3/index.html 中文版&#xff1a;https://mybatis.p2hp.com/ 搭建环境 /* SQLyog Ultimate v10.00 Beta1 MySQL - 8.0.30 : Database - mybatis-label *****************…

智能体开发:推理-行动(ReAct)思维链提示

人类在处理一个需要多个步骤才能完成任务时&#xff0c;显著特点是能够将言语推理&#xff08;内心独白&#xff09;和实际行动融合在一起&#xff0c;在面对陌生或不确定的情况时通过这种方法学习新知识&#xff0c;做出决策&#xff0c;并执行&#xff0c;从而应对复杂的任务…

*VulnHub-FristiLeaks:1.3暴力解法、细节解法,主打软硬都吃,隧道搭建、寻找exp、提权、只要你想没有做不到的姿势

*VulnHub-FristiLeaks:1.3暴力解法、细节解法&#xff0c;主打软硬都吃&#xff0c;隧道搭建、寻找exp、提权、只要你想没有做不到的姿势 一、信息收集 1、扫靶机ip 经典第一步&#xff0c;扫一下靶机ip arp-scan -l 扫描同网段 nmap -sP 192.168.122.0/242、指纹扫描、端口…