简单的排序算法

目录

1.直接插入排序

2.希尔排序

3.选择排序

4.冒泡排序

5.计数排序

6.排序总结


1.直接插入排序

(1)思想

所谓插入排序,就是将待排序数据插入到已经有序的数据中,为了使插入后数据依然有序,就要选中一个合理的位置进行插入。

(1)定义变量i,遍历待排序数据,定义遍历j,遍历已有序数据。

(2)把i指向的值存入临时遍历tmp中,遍历有序数据

(3)如果j指向的值>tmp,让j位置元素向后移动,j--;否则不移动,结束循环 

图示展示思想:

第一步: 

第二步:比较,交换数据 

第二轮:

不断类推,直到有序(i走到非法位置)

(2)代码

代码需要完整,则要判断数组是否合法有数据等等,下面不做补充

public static void insertSort(int[] array) {
        if(array == null) {
            return;
        }
        if(array.length <= 1) {
            return;
        }
        for (int i = 1; i < array.length; i++) {
            int tmp = array[i];
            int j = i -1;
            for (; j >= 0; j--) {
                if(array[j] > tmp) {
                    array[j+1] = array[j];//元素后移
                }else {
                    break;
                }
            }
            array[j+1] = tmp;//放回元素
        }
    }

前面就是为给tmp找一个合理的位置,如果j<tmp,则可以提前结束循环;否则需要走完j

(3)总结

1.时间复杂度:O(N^2)。

2.空间复杂度:O(1)。

3.稳定性:稳定。

4.适应对象:元素越有序,效率越高

2.希尔排序

希尔排序就是一种特殊的直接插入排序(在它的基础上进行优化操作),比直接插入排序1效率更高。

(1)思想

1.将数据分组,每组分别进行插入排序(作为一轮)。

2.进行第二轮,缩小组距(分组后数据增加),继续进行插入排序。

3.最后一轮时,就是对原始数据进行插入排序(此时数据已经趋于有序)。

如何分组:定义一个变量gap,称为组距。也就是每间隔五个数据就有一个数据是这个组的。

 分组的间距从大到小,一开始,我们先赋值为数组的长度。下面代码的写法可以保证gap最后一次为1,完成最后的插入排序

public static void shellSort(int[] array) {
        int gap = array.length;
        while(gap > 1) {
            gap /= 2;
            shell(array,gap);//进行插入排序
        }

    }

分组后,在组内进行插入排序即可。

如何确定:无序数据和有序数据

得出插入排序部分代码:

 j每次移动的距离就是gap,保证在同组内移动。j循环结束代表一组的插入排序完成,进入下一轮(也就是下一组);

 private 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;
        }
    }

进入下一组:

(2)完整代码

 public static void shellSort(int[] array) {
        int gap = array.length;
        while(gap > 1) {
            gap /= 2;
            shell(array,gap);//进行插入排序
        }

    }
    private 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;
        }
    }

(3)总结

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

2.时间复杂度不好计算,暂时按:O(n^1.25)-O(1.6*n^1.25)计算

3.稳定性:不稳定

3.选择排序

选择排序思想比较简单,但是时间效率很低。每轮遍历完整个数组,找到本轮最小的放到前面;第二轮再继续遍历找到当前最小的数据再放入前面。

(1)思想

定义变量:i、j

和插入排序一样定义两个变量,但是作用不同。变量i负责遍历有序数据,而变量j遍历无序数据,负责找出当前最小元素的下标(或值)。

思路图:

根据上面的思路,可以得出下面的代码

(2)完整代码

 public static void selectSort(int[] array) {

        for (int i = 0; i < array.length-1; i++) {
            int minIndex = i;//记录当前下标
            int j = i+1;
            for(;j < array.length;j++) {
                if(array[j]<array[minIndex]) {
                    minIndex = j;//最小值下标更新
                }
            }
            swap(array,i,minIndex);
        }

    }
    public static void swap(int[] array,int i,int j) {
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }

思想和代码都比较简单,就不再做简述

(3)总结

1.效率很低,实际中少用

2.时间复杂度:O(N^2) 

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

4.稳定性:不稳定  

4.冒泡排序

冒泡排序核心,每一轮冒泡会将当前最大的元素放到最后面。每次两个数据比较,大的数据往后走。

(1)思路

待排序数组:

int[] arr = {10,9,8,7,6,5,4,3,2,1};

第一轮冒泡: 

 第二轮冒泡:

后续同理

(2)完整代码

public static void  bubbleSort(int[] array) {

        for (int i = 0; i < array.length-1; i++) {
            for (int j = 0; j < array.length-i-1; j++) {
                if(array[j] > array[j+1]) {
                    int tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
                }
            }
        }
    }

为了应对逆序的代码,可以做出以下优化

public static void  bubbleSort(int[] array) {

        for (int i = 0; i < array.length-1; i++) {
            boolean bool = true;
            for (int j = 0; j < array.length-i-1; j++) {
                if(array[j] > array[j+1]) {
                    bool = false;
                    int tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
                }
            }
            if(bool) {
                break;
            }
        }
    }

如果一轮比较下来,都没有发生交换,说明已经排好序了

(3)总结

1.时间复杂度:O(N^2)

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

3.稳定性:稳定  

5.计数排序

适用场景(局限性):数据基本趋于一个区间内,如:待排序数据的值都是处于0-10的范围内

(1)思路步骤

第一步:求这组数据的最大值和最小值。

第二步:创建一个计数数组,大小为这批数据的差值。

第三步:遍历原数组数组,将值作计数数组的下标,该位置++。

第四步:取出计数数组,存入原数组中

(2)完整代码

public static void countSort(int[] array) {
        //1.求最值
        int max = array[0];
        int min = array[0];
        for (int i = 1; i < array.length; i++) {
            if(array[i] > max) {
                max = array[i];
            }
            if(array[i] < min) {
                min = array[i];
            }
        }
        //2.创建计数数组并初始化
        int[] count = new int[max-min+1];
        //3.遍历数组
        for (int i = 0; i < array.length; i++) {
            int index = array[i];
            count[index-min]++;
        }
        //4.取出计数数组
        int k = 0;
        for (int i = 0; i < count.length; i++) {
            int len = count[i];

           while (len != 0) {
               array[k] = i+min;
               k++;
               len--;
           }
        }
    }

(3)总结

(1)局限性较大,空间换取时间

(2)时间复杂度:O(范围+n)

(3)空间复杂度:O(范围)

(4)稳定性:可以稳定

6.排序总结

排序方法最好时间最坏时间空间稳定性
插入排序O(n)O(n^2)O(1)稳定
希尔排序O(n)O(n^2)O(1)不稳定
选择排序O(n^2)O(n^2)O(1)不稳定
堆排序O(n*logn)O(nlogn)O(1)不稳定
冒泡排序O(n)O(n^2)O(1)稳定
快速排序O(n*logn)O(n*logn)O(logn)-O(n)不稳定
归并排序O(n*logn)O(n*logn)O(n)稳定

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

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

相关文章

android开发网络通信,带你彻底搞懂Android启动速度优化

实现方案 直接依赖 这种方式实现简单&#xff0c;但是耦合太严重&#xff0c;不方便维护与开发&#xff0c;当工程逐渐增大模块逐渐增多&#xff0c;依赖关系会非常复杂&#xff0c;不推荐这种方式。 事件或广播通信 EventBus&#xff1a; 我们非常熟悉的事件总线型的通信框…

JavaScript的`bind`方法:函数的“复制”与“定制”

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

jquery选择器有哪些

jQuery是一个功能强大的JavaScript库&#xff0c;它提供了丰富的选择器来帮助开发者更方便地选择和操作DOM元素。以下是jQuery的一些常用选择器及其示例代码&#xff1a; 1.基本选择器&#xff1a; // 通过ID选择元素 $("#myId").css("color", "red…

【论文阅读 VLDB22】On-Demand State Separation for Cloud Data Warehousing

On-Demand State Separation for Cloud Data Warehousing 问题背景 首先是问题背景&#xff0c;目前除了大规模PB级别的AP会使用云数据库&#xff0c;越来越多的百G大小的中小规模的负载也开始进行上云分析和处理&#xff0c;而这些ap任务不需要消耗整个集群的资源&#xff0…

DHCP自动获取IP地址实验(思科)

华为设备参考&#xff1a;DHCP自动获取IP地址实验&#xff08;华为&#xff09; 一&#xff0c;实验目的 路由器搭载DHCP&#xff0c;让PC通过DHCP自动获取IP地址 二&#xff0c;不划分vlan 实验拓扑 配置命令 Switch Switch>enable Switch#configure terminal Switch(c…

C#不可识别的数据库格式解决方法

1.检查数据库文件路径和文件名&#xff1a; 确保指定的路径和文件名拼写正确&#xff0c;而且文件确实存在于指定的位置。使用绝对路径或相对路径都是可行的&#xff0c;但要确保路径的正确性 string connectionString "ProviderMicrosoft.ACE.OLEDB.12.0;Data SourceE:…

go 程序被意外kill后出现僵尸进程解决方案

go 管理自身子进程(防止僵尸进程出现) 写这篇文章是因为最近有同事竟然会知道异步启动子进程&#xff0c;不会关闭&#xff0c;最后导致导致僵尸进程出现&#xff0c;而且由于子进程会随着业务的使用越开越多&#xff0c;主进程一旦被kill掉就会不得不手动一个一个kill。 大概…

【车辆安全管理】强制降速系统

在很久之前&#xff0c;我们就讨论过车辆强制降速系统的重要性&#xff0c;即使驾驶人故意撞人&#xff0c;也难以做到&#xff0c;因为强制降速系统会控制车辆的速度。强降速系统可以通过多种传感器进行智能分析&#xff0c;即使降速。 汽车的Robot化概念-CSDN博客 最近发生…

LiveGBS流媒体平台GB/T28181功能-集中录像存储前端设备录像回看解决方案设备录像|云端录像|实时录像说明

LiveGBS集中录像存储前端设备录像回看解决方案设备录像|云端录像|实时录像说明 1、平台概述2、视频录像2.1、设备录像2.1.1、存储位置2.1.1.1、下级硬件设备2.1.1.2、下级国标平台 2.1.2、页面操作2.1.2.1、国标设备2.1.2.1.1、查看通道2.1.2.1.1.1、设备录像 2.1.2.1.2、配置中…

城市平均高温、平均低温数据爬取与可视化

爬取历史天气网站数据 从天气网站爬取指定城市、指定时间范围内的天气数据&#xff0c;并将数据保存为CSV文件。具体而言&#xff0c;它使用了Selenium库来模拟浏览器行为&#xff0c;以便获取动态加载的页面内容。 主要步骤如下&#xff1a; 读取城市信息和代理IP信息&…

Nodejs 第四十九章(lua)

lua Lua是一种轻量级、高效、可嵌入的脚本语言&#xff0c;最初由巴西里约热内卢天主教大学&#xff08;Pontifical Catholic University of Rio de Janeiro&#xff09;的一个小团队开发而成。它的名字"Lua"在葡萄牙语中意为"月亮"&#xff0c;寓意着Lua…

【QT】 QTreeView/QTreeWidget插入文件目录列表

目录 1 QTreeView插入文件目录列表 1.1 自定义默认展开指定路径及文件 1.2 展开指定路径的所有目录及文件 2 QTreeWidget插入文件目录列表 1 QTreeView插入文件目录列表 显示指定磁盘下的目录&#xff0c;简单的方式就是利用QTreeViewQDirModel就可以显示了。 1.1 自定义默认…

05_Mongooes

Mongooes Mongoose是通过Node来操作MongoDB的一个模块。是基于Node.js的第三方模块。 一、Node.js安装 1.解压 2.创建文件夹 解压路径下&#xff0c;创建两个文件夹 node_global&#xff1a;全局安装位置 node_cache&#xff1a;缓存 3.配置 配置环境变量 在path路径…

Open3D(C++) 指定点数的体素滤波

目录 一、算法原理1、算法过程2、参考文献二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 1、算法过程 对于数据量较大的点云,在后期进行配准时会影响计算效率。而体素格网…

03. Nginx入门-Nginx虚拟主机

Nginx虚拟主机简介 yum安装与源码安装一样&#xff0c;只是Nginx配置文件路径不一致&#xff0c;这里用的yum安装的配置文件路径。 利用虚拟主机的功能&#xff0c;可以在一台Nginx服务器上部署一个或多个虚拟主机。 虚拟主机主配置文件 注意&#xff1a;配置完成Nginx主配置…

【如何在Docker中,修改已经挂载的卷(Volume)】

曾梦想执剑走天涯&#xff0c;我是程序猿【AK】 提示&#xff1a;添加投票&#xff01;&#xff01;&#xff01; 目录 简述概要知识图谱 简述概要 如何在Docker中&#xff0c;修改已经挂载的卷&#xff08;Volume&#xff09; 知识图谱 在Docker中&#xff0c;修改已经挂载…

基于SSM SpringBoot vue个人博客网站

基于SSM SpringBoot vue个人博客网站 系统功能 首页 图片轮播 博客文章 搜索 登录注册 论坛 留言板 个人中心 我的收藏 后台管理 登录 个人中心 博客分类管理 博客文章管理 论坛管理 系统管理 管理员管理 注册用户管理 开发环境和技术 开发语言&#xff1a;Java 使用框架:…

API 测试- Postman Vs Rest Assured

【软件测试面试突击班】2024吃透软件测试面试最全八股文攻略教程&#xff0c;一周学完让你面试通过率提高90%&#xff01;&#xff08;自动化测试&#xff09; 介绍&#xff1a; 创新和现代化的目标已经从简单的市场差异化转变为更有道德地追求整个社会的进步。提出了新的要求…

03按键控制LED

上回讲到点亮一个LED     这次我们来实现用按键控制led 不带中断的方式 当然实例来源网络 加上自己整合 先熟悉流程 0.添加一个自己写的驱动库文件 为什么添加 笔者想的是一个项目工程希望能适应很多个应用场景需要什么直接在里面调用分装好的函数就行 1.如何添加文件以及…

AI改变游戏规则:内容创作的新时代!

AI技术&#xff0c;尤其是人工智能&#xff08;AI&#xff09;在内容创作领域的应用&#xff0c;正开启了一个全新的时代。这一时代的核心在于利用AI的能力&#xff0c;不仅提高内容创作的效率&#xff0c;还能引入前所未有的创新元素&#xff0c;从而彻底改变游戏规则。 AI在…