【算法篇】七大基于比较的排序算法精讲

news2024/11/19 16:48:53

目录

排序 

1.直接插入排序

2.希尔排序

3.直接选择排序

4.堆排序

5.冒泡排序

6.快速排序

7.归并排序


排序 

排序算法的稳定性:假设在待排序的序列中,有多个相同的关键字,经过排序后,这些关键字的先后顺序不发生改变,我们称这种排序算法是稳定的,否则是不稳定的。

把数据元素全部放在内存中进行排序我们称为内部排序

元素太多无法全部同时放在内存中,内存和外存相互结合使用的排序我们称为外部排序

 根据排序算法是否基于排序,可以将算法分为两种,而在基于排序的算法中最常见的算法有七种,分别是:直接插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序。

其中某些排序方法的实现思想相似,我们可进行如下分类:

插入排序:   1.直接插入排序           2.希尔排序

选择排序:   1.选择排序                  2.堆排序

交换排序:   1.冒泡排序                  2.快速排序

归并排序:    归并排序

1.直接插入排序

直接插入排序是一种简单的插入排序法,其基本思想是:
把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。

//1.插入排序
    public void insort(int[] arr){
        for(int i=1;i<arr.length;i++){
            int ret=arr[i];
            int j=i-1;
            for(;j>=0;j--){
                if(arr[j]>ret){
                    arr[j+1]=arr[j];
                }else{
                    break;
                }
            }
            arr[j+1]=ret;
        }
    }

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

2.希尔排序

因为直接插入排序对于越有序的数组,时间复杂度越低,所以就有大佬发明了希尔排序,希尔排序的作用就是通过分组调整将无序的数组一步一步变得接近有序,最后组数为1时,数组有序。

希尔排序法又称缩小增量法。希尔排序法的基本思想是:

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


 

    //2.希尔排序
    public void shellSort(int[] arr){
        //gap表示每组元素之间间隔的位置。
        int gap= arr.length;
        while(gap>1){
            gap/=2;
            shell(arr,gap);
        }
    }

    private void shell(int[] arr, int gap) {
        for(int i=gap;i<arr.length;i++){
            int ret=arr[i];
            int j=i-gap;
            for(;j>=0;j-=gap){
                if(arr[j]>ret){
                    arr[j+gap]=arr[j];
                }else{
                    break;
                }
            }
            arr[j+gap]=ret;
        }
    }

 希尔排序的特性总结:
1. 希尔排序是对直接插入排序的优化。
2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。
3. 希尔排序的时间复杂度与gap的取值有关,很难直接计算,根据Knuth在《计算机程序设计技巧》中的说明,当n很大时,时间复杂度可按O(N^1.25)到O(1.6*N^1.25)来计算。

4.稳定性:不稳定。

3.直接选择排序

基本思想:

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

    //3.直接选择排序
    public void chooseSort(int[] arr){
        for(int i=0;i<arr.length;i++){
            for(int j=i+1;j<arr.length;j++){
                if(arr[j]<arr[i]){
                    int ret=arr[i];
                    arr[i]=arr[j];
                    arr[j]=ret;
                }
            }
        }
    }

特性总结:

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

4.堆排序

堆排序(Heapsort)是指:

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

详细代码实现过程请看我的上一篇文章对堆进行了详细讲解:【数据结构七】堆与PriorityQueue详解

特性总结:

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

5.冒泡排序

基本思想:

冒泡排序是一种典型的交换排序,根据序列中两个相邻记录键值的比较结果来对换这两个记录在序列中的位置 。交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

    //5.冒泡排序
    public void bubbleSort(int[] arr){
        for(int i=arr.length-1;i>0;i--){
            for(int j=0;j<i;j++){
                if(arr[j+1]<arr[j]){
                    int tmp=arr[j+1];
                    arr[j+1]=arr[j];
                    arr[j]=tmp;
                }
            }
        }
    }

冒泡排序的特性总结:

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

6.快速排序

快速排序是在二叉树的前序遍历的基础上改进的一个算法,取基准值时要尽量保证左右两个区间的大小相等,这样的时间复杂度最低,在构建代码的时候我们尽量依据这一点来优化代码。

基本思想:

任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

    //6.快速排序
    public void quickSort(int[] arr){
        quick(arr,0,arr.length-1);
    }
    //快速排序的主要实现
    private void quick(int[] arr, int left, int right) {
        if(right-left<1){
            return;
        }
        int prev=midnum(arr,left,right);
        int tmp=arr[prev];
        int cur1=left;
        int cur2=right;
        while(cur1<cur2){
            while (cur1<cur2&&arr[cur2]>=tmp){
                cur2--;
            }
            while (cur1<cur2&&arr[cur1]<=tmp){
                cur1++;
            }
            swap(arr, cur1, cur2);
        }
        swap(arr,left,cur1);
        quick(arr,left,cur1);
        quick(arr,cur1+1,right);
    }
    //交换两个元素位置
    private static void swap(int[] arr, int cur1, int cur2) {
        int tmp= arr[cur1];
        arr[cur1]= arr[cur2];
        arr[cur2]=tmp;
    }
    //创建一个方法求三个值的中间值,为了优化算法。
    private int midnum(int[] arr,int left,int right){
      int mid=(left+right)/2;
      if(arr[left]<arr[right]){
          if(arr[mid]<arr[left]){
              return left;
          }else if(arr[mid]>arr[right]){
              return right;
          }else{
              return mid;
          }
      }else{
          if(arr[mid]<arr[right]){
              return right;
          }else if(arr[mid]>arr[left]){
              return left;
          }else{
              return mid;
          }
      }
    }

特性总结:

1.快速排序整体的综合性能和使用场景都是比较好的。
2. 时间复杂度:O(N*logN)
3. 空间复杂度:O(logN)
4. 稳定性:不稳定

7.归并排序

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。

基本思想:

将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

    //7.归并排序
    public void mergeSort(int[] arr){
        mergeSortFun(arr,0,arr.length-1);
    }

    private void mergeSortFun(int[] arr, int left, int right) {
        if(left>=right){
            return;
        }
        int mid=(left+right)/2;
        mergeSortFun(arr,left,mid);
        mergeSortFun(arr,mid+1,right);
        merge(arr,left,mid,right);
    }

    private void merge(int[] arr, int left, int mid, int right) {
        int s1=left;
        int e1=mid;
        int s2=mid+1;
        int e2=right;
        int[] tmpArr=new int[right-left+1];
        int k=0;
        while(s1<=e1&&s2<=e2){
            if(arr[s1]<=arr[s2]){
                tmpArr[k]=arr[s1];
                s1++;
                k++;
            }else{
                tmpArr[k]=arr[s2];
                s2++;
                k++;
            }
        }
        while(s1<=e1){
            tmpArr[k]=arr[s1];
            s1++;
            k++;
        }
        while(s2<=e2){
            tmpArr[k]=arr[s2];
            s2++;
            k++;
        }
        for(int i=0;i< tmpArr.length;i++){
            arr[i+left]=tmpArr[i];
        }
    }

特性总结:

1. 归并的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。
2. 时间复杂度:O(N*logN)
3. 空间复杂度:O(N)
4. 稳定性:稳定
 

欢迎大家点赞加关注啊!!!,随后会更新非基于比较的算法,基数排序,桶排序和计数排序。

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

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

相关文章

动态规划8, 摆动序列,最长递增子序列,最长数对链

本次的题与动态规划7 的题有相似与共通之处&#xff0c;建议先去看 动态规划7&#xff1a;动态规划7 摆动序列 什么是摆动序列&#xff1f; 就像这种&#xff1a; 一个数&#xff0c;一个下降&#xff0c;上升&#xff0c;来回上升下降都可以叫摆动序列。 思路&#xff1a; …

政安晨:【深度学习处理实践】(八)—— 表示单词组的两种方法:集合和序列

咱们接着这个系列的上一篇文章继续&#xff1a; 政安晨&#xff1a;【深度学习处理实践】&#xff08;七&#xff09;—— 文本数据预处理https://blog.csdn.net/snowdenkeke/article/details/136697057 机器学习模型如何表示单个单词&#xff0c;这是一个相对没有争议的问题…

分析基于解析物理模型的E模式p沟道GaN高电子迁移率晶体管(H-FETs)

来源&#xff1a;Analyzing E-Mode p-Channel GaN H-FETs Using an Analytic Physics-Based Compact Mode&#xff08;TED 24年&#xff09; 摘要 随着近期对用于GaN互补技术集成电路&#xff08;ICs&#xff09;开发的p沟道GaN器件研究兴趣的激增&#xff0c;一套全面的模型…

算法笔记 连载中。。。

HashMap&#xff08;会根据key值自动排序&#xff09; HashMap<String, Integer> hash new HashMap<>() hash.put(15,18) hash.getOrDefault(ts, -1) //如果ts(key)存在&#xff0c;返回对应的value 否则返回-1 hashMap1.get(words1[i])1会报错&#xff0c;因…

快速高效地数据分析处理:QtiPlot for Mac中文直装版 兼容M

QtiPlot 是一个用于数据分析和可视化的跨平台科学应用程序。由于其多语言支持&#xff0c;QtiPlot 被积极用于世界各地学术机构的教学。许多研究科学家信任 QtiPlot 来分析他们的数据并发布他们的工作结果。来自各个科学领域和行业的数千名注册用户已经选择了 QtiPlot 来帮助他…

SQLiteC/C++接口详细介绍之sqlite3类(十五)

返回目录&#xff1a;SQLite—免费开源数据库系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;十四&#xff09; 下一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;十六&#xff09; 47.sqlite3_set_authorizer 用法&#xff…

【Preprocessing数据预处理】之Scaler

在机器学习中&#xff0c;特征缩放是训练模型前数据预处理阶段的一个关键步骤。不同的缩放器被用来规范化或标准化特征。这里简要概述了您提到的几种缩放器&#xff1a; StandardScaler StandardScaler 通过去除均值并缩放至单位方差来标准化特征。这种缩放器假设特征分布是正…

Seata 2.x 系列【9】事务会话存储模式

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Seata 版本 2.0.0 本系列Spring Boot 版本 3.2.0 本系列Spring Cloud 版本 2023.0.0 源码地址&#xff1a;https://gitee.com/pearl-organization/study-seata-demo 文章目录 1. 概述2. 存储模…

虚拟机网络链接

在虚拟网络设置中找到如下界面&#xff1a; "子网 IP" 192.168.79.0/24 表示一个局域网络&#xff0c;它有254个可能的IP地址可供分配&#xff08;192.168.79.1到192.168.79.254&#xff09;&#xff0c;255.255.255.0 是子网掩码&#xff0c;定义了网络和主机部分。…

MySQL--深入理解MVCC机制原理

什么是MVCC&#xff1f; MVCC全称 Multi-Version Concurrency Control&#xff0c;即多版本并发控制&#xff0c;维持一个数据的多个版本&#xff0c;主要是为了提升数据库的并发访问性能&#xff0c;用更高性能的方式去处理数据库读写冲突问题&#xff0c;实现无锁并发。 什…

Cartwheel——文本生成3D动作或动画的工具

一个强大的文本转3D动画平台,用户只需通过输入文字提示即可生成视频、游戏、电影、广告、社交或VR项目所需的3D动画角色。 Cartwheel 是一个功能强大的文本到动画平台。只需键入即可为您的视频、游戏、电影、广告、社交或 VR 项目制作角色动画 定位: 定位于为用户提供简单…

Unity类银河恶魔城学习记录10-11 p99 Aliment visual effects源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili EntityFX.cs using System.Collections; using System.Collections.Gener…

Mysql事务+锁测试 RR行锁升级

Mysql事务锁测试 Mysql5.7 在隔离级别RR下&#xff0c;添加写锁&#xff0c;锁住一行数据&#xff0c;写锁是排它锁&#xff0c;不允许其它的读写、 另外开启一个连接&#xff0c;进行写操作&#xff0c;发现执行没有成功&#xff0c;在等待锁 查询事务表&#xff0c;有两个事…

openssl3.2 - note - Decoders and Encoders with OpenSSL

文章目录 openssl3.2 - note - Decoders and Encoders with OpenSSL概述笔记编码器/解码器的调用链OSSL_STORE 编码器/解码器的名称和属性OSSL_FUNC_decoder_freectx_fnOSSL_FUNC_encoder_encode_fn官方文档END openssl3.2 - note - Decoders and Encoders with OpenSSL 概述 …

大数据Doris(六十八):基于Doris on ES的架构实现总结

文章目录 基于Doris on ES的架构实现总结 一、Mem Join架构遗留的核心问题 二、Doris

河南大学大数据平台技术实验报告二

大数据平台技术课程实验报告 实验二&#xff1a;HDFS操作实践 姓名&#xff1a;杨馥瑞 学号&#xff1a;2212080042 专业&#xff1a;数据科学与大数据技术 年级&#xff1a;2022级 主讲教师&#xff1a;林英豪 实验时间&#xff1a;2024年3月15日3点 至 2024年3月15日4点40 …

力扣经典题:分割平衡字符串

大佬的代码非常简洁 int balancedStringSplit(char * s){short i0,count0,sign0;while(s[i]){signs[i]L?sign1:sign-1;if(sign0) count;}return count; }

安装gpu-torch(已经成功)

### &#xff01;&#xff01;&#xff01;直接使用pip安装&#xff0c;不要使用conda安装&#xff0c;使用conda安装总是会安装成CPU版本。 1.第一次尝试 之前按照官网安装pytorch的命令进行安装&#xff0c;结果安装出来是cpu版本的&#xff0c;试过https://blog.csdn.net/…

【日常记录】【CSS】css下划线动画

文章目录 1、效果2、思路3、代码 1、效果 2、思路 整体可以用 背景来做线&#xff1a;可以用 渐变 配合 background-size 、 background-position 、background-repeat正向动画&#xff1a;可以不断追加 background-size x 轴的大小来控制&#xff0c;当鼠标移入的时候&#x…

【应急响应靶场web2】

文章目录 前言 一、应急响应 1、背景 2、webshell查杀 3、日志排查 1&#xff09;apache日志 2&#xff09;nginx日志 3&#xff09;ftp日志 4、隐藏账户 5、文件筛选 二、漏洞复现 总结 前言 靶场来源&#xff1a;知攻善防实验室 一、应急响应 1、背景 小李在某…