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

目录

排序 

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. 稳定性:稳定
 

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring项目问题—前后端交互:Method Not Allowed

问题 前后端交互时出现Method Not Allowed问题 Ajax中使用的是get&#xff0c;方法仍然出现post方法报错 Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method POST not supported] 浏览器中没有报错&#xff0c;只是接收不到后端返…

解锁数据潜力:OceanBase国产数据库学习不容错过的秘密!

介绍&#xff1a;OceanBase是一款由阿里巴巴和蚂蚁金服自主研发的通用分布式关系型数据库&#xff0c;它专为企业级应用而设计&#xff0c;具有金融级别的可靠性。以下是对OceanBase的详细介绍&#xff1a; 高可用性&#xff1a;OceanBase通过实现Paxos多数派协议和多副本特性&…

MySql入门教程--MySQL数据库基础操作

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

C语言从入门到熟悉------第四阶段

指针 地址和指针的概念 要明白什么是指针&#xff0c;必须先要弄清楚数据在内存中是如何存储的&#xff0c;又是如何被读取的。如果在程序中定义了一个变量&#xff0c;在对程序进行编译时&#xff0c;系统就会为这个变量分配内存单元。编译系统根据程序中定义的变量类型分配…

【滤波专题-第8篇】ICA降噪方法——类EMD联合ICA降噪及MATLAB代码实现(以VMD-ICA为例)

今天来介绍一种效果颇为不错的降噪方法。&#xff08;针对高频白噪声&#xff09; 上一篇文章我们讲到了FastICA方法。在现实世界的许多情况下&#xff0c;噪声往往接近高斯分布&#xff0c;而有用的信号&#xff08;如语音、图像特征等&#xff09;往往表现出非高斯的特性。F…

unity学习(60)——选择角色界面--MapHandler2-MapHandler.cs

1.新建一个脚本&#xff0c;里面有static变量loadingPlayerList using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace Assets.Scripts.Model {internal class LoadData{public static List<Pl…

3D地图在BI大屏中的应用实践

前言 随着商业智能的不断发展&#xff0c;数据可视化已成为一项重要工具&#xff0c;有助于用户更好地理解数据和分析结果。其中&#xff0c;3D地图作为一种可视化工具&#xff0c;已经在BI大屏中得到了广泛地应用。 3D地图通过将地理信息与数据相结合&#xff0c;以更加直观…

【AI】用iOS的ML(机器学习)创建自己的AI App

用iOS的ML(机器学习)创建自己的AI App 目录 用iOS的ML(机器学习)创建自己的AI App机器学习如同迭代过程CoreML 的使用方法?软件要求硬件开始吧!!构建管道:设计和训练网络Keras 转 CoreML将模型集成到 Xcode 中结论推荐超级课程: Docker快速入门到精通Kubernetes入门到…

计算机网络——物理层(数据通信基础知识)

计算机网络——物理层&#xff08;1&#xff09; 物理层的基本概念数据通信的基本知识一些专业术语消息和数据信号码元 传输速率的两种表示方法带宽串行传输和并行传输同步传输和异步传输 信道基带信号调制常用编码方式 我们今天进入物理层的学习&#xff0c;如果还没有了解OSI…

Transformer代码从零解读【Pytorch官方版本】

文章目录 1、Transformer大致有3大应用2、Transformer的整体结构图3、如何处理batch-size句子长度不一致问题4、MultiHeadAttention&#xff08;多头注意力机制&#xff09;5、前馈神经网络6、Encoder中的输入masked7、完整代码补充知识&#xff1a; 1、Transformer大致有3大应…

C++ 入门篇

目录 1、了解C 2、C关键字 2、命名空间 2.1 命名空间的定义 2.2 命名空间的使用 3. C输入与输出 4.缺省参数 4.1 缺省参数的概念 4.2 缺省参数的分类 5. 函数重载 5.1 函数重载的概念 5.2 C中支持函数重载的原理--名字修饰 6. 引用 6.1 引用概念 6.2 引用…

Docker 系列2【docker安装mysql】【开启远程连接】

文章目录 前言开始步骤1.增加mysql挂载目录2.下载镜像2.启动容器具体步骤4.无法连接5.测试连接 总结 前言 本文开始&#xff0c;默认已经安装docker&#xff0c;如果你还没有完成这个步骤&#xff0c;请查看这一篇文章【docker安装与使用】 开始步骤 1.增加mysql挂载目录 m…

网络原理(1)——UDP协议

目录 一、应用层 举个例子&#xff1a;点外卖 约定数据格式简单粗暴的例子 客户端和服务器的交互&#xff1a; 序列化和返序列化 xml、json、protobuffer 1、xml 2、json 3、protobuffer 二、传输层 端口 端口号范围划分 认识知名的端口号 三、UDP协议 端口 U…

宜搭faas服务器报错Network response was not OK

[error] https://api.dingtalk.com/v1.0/yida/forms/instances? fetch error Error: Network response was not OK 不出意外的话肯定是请求代码的某个部分出了问题&#xff1a;其中formInstanceId和updateFormDataJson是业务的内容 我检查过是没问题的。appType和systemToken…

面试经典-MySQL篇

一、MySQL组成 MySQL数据库的连接池&#xff1a;由一个线程来监听一个连接上请求以及读取请求数据&#xff0c;解析出来一条我们发送过去的SQL语句SQL接口&#xff1a;负责处理接收到的SQL语句查询解析器&#xff1a;让MySQL能看懂SQL语句查询优化器&#xff1a;选择最优的查询…

【C#】【SAP2000】读取SAP2000中所有Frame对象在指定工况的温度荷载值到Grasshopper中

if (build true) {// 连接到正在运行的 SAP2000// 使用 COM 接口获取 SAP2000 的 API 对象cOAPI mySapObject (cOAPI)System.Runtime.InteropServices.Marshal.GetActiveObject("CSI.SAP2000.API.SapObject");// 获取 SAP2000 模型对象cSapModel mySapModel mySap…

Vue 项目安装依赖提示core-js版本低的处理办法

core-js2.6.12: core-js<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js3. 我是下载一个老的项目&#xff0c;npm install之后提示上面的错误&#xff1b;本…

Linux——ELK日志分析系统

实验环境 虚拟机三台CentOS 7.9&#xff0c; 组件包 elasticsearch-5.5.0.rpm elasticsearch-head.tar.gz node-v8.2.1.tar.gz phantomjs-2.1.1-linux-x86_64.tar.bz2 logstash-5.5.1.rpm kibana-5.5.1-x86_64.rpm 初始…

分享一下自己总结的7万多字java面试笔记和一些面试视频,简历啥的,已大厂上岸

分享一下自己总结的7万多字java面试笔记和一些面试视频&#xff0c;简历啥的&#xff0c;已大厂上岸 自己总结的面试简历资料&#xff1a;https://pan.quark.cn/s/8b602fe53b58 文章目录 SSMspringspring 的优点&#xff1f;IoC和AOP的理解**Bean 的生命周期****列举一些重要…

C++进阶:详解多态(多态、虚函数、抽象类以及虚函数原理详解)

C进阶&#xff1a;详解多态&#xff08;多态、虚函数、抽象类以及虚函数原理详解&#xff09; 结束了继承的介绍&#xff1a;C进阶&#xff1a;详细讲解继承 那紧接着的肯定就是多态啦 文章目录 1.多态的概念2.多态的定义和实现2.1多态的构成条件2.2虚函数2.2.1虚函数的概念2…