【JAVA】七大排序算法(图解)

news2024/11/16 23:50:02

稳定性: 待排序的序列中若存在值相同的元素,经过排序之后,相等元素的先后顺序不发生改变,称为排序的稳定性。

思维导图:

(排序名称后面蓝色字体为时间复杂度和稳定性
在这里插入图片描述


1.直接插入排序

核心思路

每次从无序区间中选择第一个元素,插入到有序区间的合适位置,直到整个数组有序。

排序步骤

  1. 定义下标 i 为当前无序区间的第一个元素, i-1 表示有序区间的最大值,下标 j 从后往前遍历有序区间。
  2. 有序区间:[0…i)
  3. 无序区间:[i…n)
  4. 若arr[i]>arr[i-1],直接将arr[i]纳入有序区间即可。
  5. 若arr[i]<arr[i-1],交换arr[i]和arr[i-1],i- -继续比较。

在这里插入图片描述

代码

    public static void insert(int[]arr){
        //有序区间:[0,i)
        //无序区间:[i,n)
        int n=arr.length;
        //i指向当前无序区间的第一个元素
        for (int i = 1; i < n; i++) {
            for (int j = i; j >=1 && arr[j]<arr[j-1]; j--) {
                    int temp=arr[j];
                    arr[j]=arr[j-1];
                    arr[j-1]=temp;
            }
        }
    }

优点

插入排序再近乎有序的集合上性能非常好!!!

只有当前一个元素大于后一个元素时,才需要交换,若前一个元素小于后一个元素,则不需要走第二层循环。


2.希尔排序

核心思路

希尔排序其实是对插入排序的一种优化。

先将待排序的数组分为若干个子数组。将子数组调整为有序状态,不断变大这个分组长度,当最终分组长度为1时,整个数组接近有序。最后来一次插入排序即可。

排序步骤

在这里插入图片描述

我们来举一个实例:

在这里插入图片描述

  1. 首先gap取5,此时相隔距离为5的元素分到了一组(一共五组,每组两个元素),然后对每一组分别进行插入排序

在这里插入图片描述

  1. gap折半为2,此时相隔距离为2的元素被分到了一组(一共两组,每组五个元素),然后对每一组分别进行插入排序

在这里插入图片描述

  1. gap再次折半为1,此时所有元素被分到了一组,对它进行插入排序,至此插入排序完成
    在这里插入图片描述

本例中前两趟就是希尔排序的预排序,最后一趟就是希尔排序的插入排序。

代码

    private static void insertionSortByGap(int[] arr, int gap) {
        for (int i = gap; i < arr.length; i++) {
            for (int j = i; j-gap>=0 && arr[j]<arr[j-gap]; j-=gap) {
                int temp=arr[j];
                arr[j]=arr[j-gap];
                arr[j-gap]=temp;
            }
        }
    }

3.直接选择排序

核心思路

直接选择排序:每次在无序区间中选择最小值与无序区间的第一个元素交换,直到整个数组有序。

排序步骤

  1. 定义下标 i 为当前无序区间的第一个元素,下标 min 为无序区间的最小值,下标 j 遍历无序区间。
  2. 有序区间:[0…i)
  3. 无序区间:[i…n)
  4. j 遍历无序数组,若 j 指向的元素小于min指向的元素,则min指向此元素。
  5. 遍历完之后,将min指向的元素与 i 指向的元素交换。
    在这里插入图片描述

代码

    public static void select(int[] arr){
        //有序区间:[0,i)
        //无序区间:[i,n)
        int n=arr.length;
        //当无序区间只剩下一个元素时,已经不用再排了
        for (int i=0; i < n-1 ; i++) {
            //min指向无序区间的最小值
            int min=i;
            for (int j = i+1 ; j < n ; j++) {
                if(arr[j]<arr[min]){
                    min=j;
                }
            }
            //此时min一定指向无序区间的最小值
            int temp=arr[i];
            arr[i]=arr[min];
            arr[min]=temp;
        }
    }

缺点

无论数组是否接近有序,直接选择排序都会执行一遍内部的排序流程,对数据不敏感。


4.堆排序

🌙原地堆排序写在另一篇文章了~

⭐原地堆排序


5.冒泡排序

核心思路

重复扫描待排序序列,并比较每一对相邻的元素,当该对元素顺序不正确时进行交换。一直重复这个过程,直到没有任何两个相邻元素可以交换,就表明完成了排序。

排序步骤

  1. 比较相邻两个数据如果。第一个比第二个大,就交换两个数
  2. 对每一个相邻的数做同样1的工作,这样从开始一队到结尾一队在最后的数就是最大的数。
  3. 针对所有元素上面的操作,除了最后一个。
  4. 重复1~3步骤,直到顺序完成。

在这里插入图片描述

代码

    public static void bubbleSort(int[]arr){
        //外层循环表示要进行元素操作的趟数
        for (int i = 0; i < arr.length-1; i++) {
            boolean isSwaped=false;
            for (int j = 0; j < arr.length-i-1; j++) {
                if(arr[j]>arr[j+1]){
                    isSwaped=true;
                    int temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
            if(!isSwaped){
                break;
            }
        }
    }

6.快速排序

🌙快速排序写在另一篇文章了~

⭐快速排序详解


7.归并排序

核心思路

1.归: 先不断的将原数组一分为二,直到拆分后的子数组只剩下一个元素。(当数组只有一个元素时,天然有序)
2.并: 不断的将两个连续的有序子数组合并为一个大的数组,直到整个数组合并完成。

在这里插入图片描述

排序步骤

并的核心步骤:给定一个临时数组 aux 存储即将归并的子数组的值。
在这里插入图片描述

代码

    public static void mergeSort(int[]arr){
        mergeSortInternal(arr,0,arr.length-1);
    }

    private static void mergeSortInternal(int[] arr, int l, int r) {
        if(l>=r){
            return;
        }
        int mid=l+((r-l)>>2);
        //先将原数组一分为二,在子数组上进行归并排序
        mergeSortInternal(arr,l,mid);
        mergeSortInternal(arr,mid+1,r);
        //此时两个子数组已经有序,将两个子数组合并为原数组
        merge(arr,l,mid,r);
    }

    private static void merge(int[] arr, int l, int mid, int r) {
        //创建一个临时数组
        int[] aux=new int[r-l+1];
        //拷贝子数组的数据到临时数组上
        System.arraycopy(arr,l,aux,0,r-l+1);
        //两个子数组的开始索引
        int i=l;
        int j=mid+1;
        //k表示当前原数组合并到哪个位置
        for (int k = l; k <= r; k++) {
            if(i>mid){
                //此时子数组1全部拷贝完毕,将子数组2的内容全部写回
                arr[k] = aux[j-l];
                j++;
            }else if(j>r){
                //此时子数组2全部拷贝完毕,将子数组1的内容全部写回
                arr[k] = aux[i-l];
                i++;
            }else if(aux[i-l]<=aux[j-l]){
                arr[k]=aux[i-l];
                i++;
            }else{
                arr[k]=aux[j-l];
                j++;
            }
        }
    }

补充:希尔排序的图片参考了这篇博文:希尔排序

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

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

相关文章

E1. PermuTree (easy version) Codeforces Round 890 (Div. 2) E1

题目大意&#xff1a; 给出一个n个点的树&#xff0c;所有点权a[i]构成一个n的排列&#xff0c;点权可以任意分配给点&#xff0c;问最多有多少对u,v满足a[u]<lca(a[u],a[v])<a[v] 2<n<5000 思路&#xff1a;首先&#xff0c;如果两个点的lca是他俩其中之一&…

Elasticsearch之kibana相关命令

1.中文分词器相关命令 2.拼音分词器相关命令

vuejs 设计与实现 - 双端diff算法

我们介绍了简单 Diff 算法的实现原理。简单 Diff 算法利用虚拟节点的 key 属性&#xff0c;尽可能地复用 DOM元素&#xff0c;并通过移动 DOM的方式来完成更新&#xff0c;从而减少不断地创建和销毁 DOM 元素带来的性能开销。但是&#xff0c;简单 Diff 算法仍然存在很多缺陷&a…

设备使用RTMP推流到安防监控EasyCVR视频汇聚平台,为何只有FLV格式无法播放?

TSINGSEE青犀视频安防监控视频汇聚平台EasyCVR基于云边端一体化架构&#xff0c;具有强大的数据接入、处理及分发能力&#xff0c;可提供视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级联、云台控制、语音对讲、智能分析等功能。 智能视频监控平台EasyCVR可…

镭速-解析极速文件传输软件

每天都要传输文件&#xff0c;让人心烦意乱&#xff0c;如果有一种最快的文件传输软件&#xff0c;就能节约很多时间&#xff0c;那么针对用户的这个需求&#xff0c;我们来介绍一下镭速的文件传输软件&#xff0c;看它是否真的那么快&#xff0c;快得让你惊讶。 文件传输要怎么…

vue 09 多组件项目 todolist ,组件编程三部曲,函数方式传递消息,ref,自定义事件传递消息

分析项目组件构成&#xff1a; 组件编程三部曲&#xff1a; 第一步.先创建四个需要用到的组件 由于header&#xff0c;footer&#xff0c;list&#xff0c;item都和html文件或者是js的关键字有冲突&#xff0c;所以建议改成两个单词的名字&#xff0c;MyHeader&#xff0c;My…

2542. 最大子序列的分数

题目描述&#xff1a; 主要思路&#xff1a; 这是一个堆的题目&#xff0c;首先将2里边的下标按照数值递减的顺序进行重新排列。依次遍历2的下标同时加上1的数值&#xff0c;堆里边存储1的大小。 class Solution { public:long long maxScore(vector<int>& nums1, …

Leetcode | 有效的括号、最长有效括号

一、有效的括号 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应…

用node.js搭建一个视频推流服务

由于业务中有不少视频使用的场景&#xff0c;今天来说说如何使用node完成一个视频推流服务。 先看看效果&#xff1a; 这里的播放的视频是一个多个Partial Content组合起来的&#xff0c;每个Partial Content大小是1M。 一&#xff0c;项目搭建 &#xff08;1&#xff09;初…

可靠传输-回退N帧协议

上图中&#xff0c;第一幅图为停止等待协议&#xff0c;而第二幅图为流水线传输&#xff0c;是在接收方返回确认收到的数据之前发送N个数据分组。 回退N帧协议GBN&#xff08;go-back-N&#xff09;&#xff1a; 无差错情况&#xff1a; 1.采用3个比特给分组编号&#xff0c…

从小白到大神之路之学习运维第76天-------Kubernetes工作原理(k8s)

第四阶段 时 间&#xff1a;2023年8月9日 参加人&#xff1a;全班人员 内 容&#xff1a; Kubernetes工作原理 目录 一、案例概述 传统部署时代&#xff1a; 虚拟化部署时代&#xff1a; 容器部署时代&#xff1a; 二、Kubernetes概述 &#xff08;一&#xff…

Pytorch Tutorial【Chapter 3. Simple Neural Network】

Pytorch Tutorial【Chapter 3. Simple Neural Network】 文章目录 Pytorch Tutorial【Chapter 3. Simple Neural Network】Chapter 3. Simple Neural Network3.1 Train Neural Network Procedure训练神经网络流程3.2 Build Neural Network Procedure 搭建神经网络3.3 Use Loss …

机器学习、深度学习项目开发业务数据场景梳理汇总记录二

本文的主要作用是对历史项目开发过程中接触到的业务数据进行整体的汇总梳理&#xff0c;文章会随着项目的开发推进不断更新。 这里是续文&#xff0c;因为CSDN单篇文章内容太大的话就会崩溃的&#xff0c;别问我怎么知道的&#xff0c;问就是血泪教训&#xff0c;辛辛苦苦写了一…

直播预告 | 全面解读现代发布/订阅模型

线上沙龙-技术流第 34 期营业啦 08月10日&#xff08;周四&#xff09;19:30 KaiwuDB - B站直播间 PubSub 模式在 IoT 场景下非常常见&#xff0c;可以灵活地在线配置采集数据的流向。同时 PubSub 可以使系统容易解耦&#xff0c;增加系统的横向扩展性。 本期直播我们邀请到…

8月第1周榜单丨飞瓜数据B站UP主排行榜(哔哩哔哩平台)发布!

飞瓜轻数发布2023年7月31日-8月06日飞瓜数据UP主排行榜&#xff08;B站平台&#xff09;&#xff0c;通过充电数、涨粉数、成长指数三个维度来体现UP主账号成长的情况&#xff0c;为用户提供B站号综合价值的数据参考&#xff0c;根据UP主成长情况用户能够快速找到运营能力强的B…

tft_espi 中文字体及自定义字体制作(tft.eSPI模块)

tft.eSPI库自定义字体方法 先下载 processing 然后安装 到mixly安装目录下找到tft_eSPI文件夹 路径如&#xff1a;D:\Mixly1.20\arduino\portable\sketchbook\libraries\TFT_eSPI\Tools 将Tools文件夹单独复制出来如我的为 E:\tft_espi字体制作Tools 在tft_espi字体制作To…

【香瓜说职场】建立公司(2017.07.25)

自从17年4月份开始辞职创业&#xff0c;已经3个多月了。跟大家分享一下创业经历。 一、我的合伙人 我的合伙人是我的客户。我给他上过蓝牙教学课、帮他做了个蓝牙自拍器&#xff08;叫orbit 360&#xff0c;已在售&#xff0c;百度能搜到&#xff09;&#xff0c;历经一年多。双…

今天学前端,还能高薪就业吗?

大学毕业3年后&#xff0c;我坚定的选择来黑马转行学前端&#xff0c;实现我的高起点就业&#xff01;希望我的一些学习和工作感悟能对学弟学妹们有所帮助。 学科 | HTML&JS前端 校区 | 武汉 薪资 | 12k 黑马程序员的学弟、学妹们大家好&#xff01;我是张同学。 选择黑…

vue基础-vue开发如何调试

文章目录 前言一、debugger二、Vue.js devtools总结 前言 对于一个前端小白来说&#xff0c;在vue项目开发过程中&#xff0c;当遇到应用逻辑出现错误&#xff0c;使用好调试工具更能准确定位到问题。所以知晓Vue项目调试技巧至关重要&#xff0c;debug是必备技能。 下面介绍…

负责任的训练数据:三个重要方面

毫无疑问&#xff0c;人工智能&#xff08;Artificial Intelligence&#xff09;技术一定会在接下来的几年中持续快速发展&#xff0c;并与我们的日常生活愈发密切地联系在一起。现在&#xff0c;企业必须要承担起责任&#xff0c;实施负责任的AI&#xff0c;以最大限度地提高透…