数据结构之八大排序(上)

找往期文章包括但不限于本期文章中不懂的知识点:

个人主页:我要学编程(ಥ_ಥ)-CSDN博客

所属专栏:数据结构(Java版) 

目录

排序的相关介绍

直接插入排序 

希尔排序(缩小增量排序)

选择排序

堆排序

冒泡排序 


排序的相关介绍

排序的概念:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。

内部排序:数据元素全部放在内存中的排序。

外部排序:数据元素太多不能同时放在内存中,根据排序的要求在内外存之间移动数据的排序。

两个5的相对位置发生了变化,就是不稳定的排序。

注意:稳定的排序,也可以变成是不稳定的排序;而不稳定的排序无法变成稳定的排序。

排序运用:我们日常生活中,在网上买东西时,根据价钱来筛选,这就用到了排序。

常见的排序算法有八种,根据对数据的处理方式分类:

下面我们就来详细学习:

直接插入排序 

思路:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。实际中我们玩扑克牌时,就用了插入排序的思想。 

思路:

代码实现:

    public static void insertSort(int[] array) {for (int i = 1; i < array.length; i++) {int j = i-1;int tmp = array[i];while (j >= 0) {if (array[j] > tmp) {// 大于,就让其往后走array[j+1] = array[j];j--;} else {// 有序就直接判断后面的break;}}// 让tmp中的值回到数组中array[j+1] = tmp;}}

时间复杂度:O(N^2):最坏情况就是数据全部是逆序的。例如:我们是要排成从小到大的顺序,数据给的是 5 4 3 2 1。然而,当数据本身就是有序的情况下,也就只会进行判断,因此这时的时间复杂度就是O(N)。这里就可以得出一个结论:数据越有序,效率越高。

空间复杂度:O(1) :只申请了常数个空间

稳定性: 稳定的排序。本身是一个稳定的排序,可以实现为不稳定的。

希尔排序(缩小增量排序)

希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成多个组, 所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取重复上述分组和排序的工作。当到达分组 =1时,所有记录在统一组内排好序。如下图所示:

这个gap的求值有很多种最常见的就是:总数据 / 2 和 总数据 / 3 + 1。

代码实现:

    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) {// i 是组内要排序的第二个数据for (int i = gap; i < array.length; i++) {// j 是组内要排序的第一个数据int j = i-gap;int tmp = array[i];while (j >= 0) {if (array[j] > tmp) {array[j+gap] = array[j];j -= gap;} else {break;}}array[j+gap] = tmp;}}

注意:

1、希尔排序是对直接插入排序的优化。

2、i 在加时,虽然 i += gap ,最终的排序结果是对的(因为gap 最终还是会等于1,就相当于直接进行直接插入排序了),但是并不符合逻辑要求。

3、当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。

4、希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算。

时间复杂度:O(n^1.3 - n^1.5):很多著名的书籍上面的估算结果。

空间复杂度:O(1):申请了常数个空间。

稳定性:不稳定。

选择排序

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

代码实现:

    public static void selectSort(int[] array) {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;}}// 交换if (minIndex != i) {swap(array, i, minIndex);}}}private static void swap(int[] array, int i, int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;}

注意: 

1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用。

2. 时间复杂度:O(N^2):无论是最好情况还是最坏情况,时间复杂度都是一样的。也就是说和数据的顺序无关。

3. 空间复杂度:O(1):申请了常数个空间。

4. 稳定性:不稳定。 

情况二属于第一个元素是重复的元素且不是最小的。 

优化:既然是找最小值,那么我们直接既找最小值又找最大值,然后两头交换即可,这样效率就提升了不少。

代码实现:

    public static void selectSort(int[] array) {int left = 0;int right = array.length-1;while (left < right) {int minIndex = left;int maxIndex = left;for (int i = left+1; i <= right; i++) {if (array[minIndex] > array[i]) {minIndex = i;}if (array[maxIndex] < array[i]) {maxIndex = i;}}// 开始交换swap(array, minIndex, left);// 如果left位置是最大值,那么第一次交换时,就会把最大值换走,换成最小值// 那么我们在第二次交换时,只会把最小值交换走,无法拿到最大值if (maxIndex == left) {maxIndex = minIndex;}swap(array, maxIndex, right);left++;right--;}}

堆排序

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是:从小到大排序得建大根堆;从大到小排序得建小根堆。想要了解更多的知识,可以去看这篇博客:数据结构之探索“堆”的奥秘-CSDN博客

思路:首先,就是要建一个大根堆,然后根据删除的思路来交换数据,再进行向下调整来重新使其变成大根堆。一直重复该步骤,直至遍历完成数组。

代码实现:

    public static void heapSort(int[] array) {// 从小到大排序建大根堆createHeap(array);// 开始排序heap_sort(array);}private static void createHeap(int[] array) {// 向下调整建堆(时间复杂度比较小:O(N))// 从最后一棵子树的位置开始向下调整建堆for (int parent = (array.length-1-1)/2 ; parent >= 0; parent--) {siftDown(array, parent, array.length);}}private static void siftDown(int[] array, int parent, int end) {int child = parent*2+1;// 大根堆while (child < end) {// 先找到左右孩子的最大值if (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;}}}private static void heap_sort(int[] array) {// 模拟删除的思想int end = array.length-1;int start = 0;while (end > 0) {swap(array, end, start);siftDown(array, start, end);end--;}}

如果这个代码有疑惑的话,可以去看上面的链接博客,那里有画图更加的清晰明了。

注意:

1. 堆排序使用堆来选数,效率就高了很多。

2. 时间复杂度:O(N*logN):向下建堆的时间复杂度为O(N) + 排序的时间复杂度为O(N*logN).

3. 空间复杂度:O(1):只申请了常数个空间。

4. 稳定性:不稳定。 

冒泡排序 

冒泡排序是属于交换排序的一种。

交换排序,基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动(从小到大排序)。 

其实这里已经告诉我们思路了,而且冒泡排序我们在C语言阶段,JavaSE阶段就进行了学习,因此下面就直接给出代码了。

代码实现:

    public static void bubbleSort(int[] array) {// 冒泡排序的特点和堆排序一样,是后面的数据先有序for (int i = 0; i < array.length-1; i++) { // 趟数boolean flag = true; // 假设数据已经有序了for (int j = 0; j < array.length-1-i; j++) { // 每一趟比较的内容if (array[j] > array[j+1]) {swap(array, j, j+1);flag = false; // 交换了,就说明数据还不是有序的}}// 如果没有交换,就说明有序,则不在交换if (flag) {break;}}}

注意:

1. 冒泡排序是一种非常容易理解的排序。

2. 时间复杂度:O(N^2):在时间复杂度那篇博客中有详细介绍,有兴趣的小伙伴可以看一看。

3. 空间复杂度:O(1):只申请了常数个空间。

4. 稳定性:稳定。和直接插入排序一样,既可以实现为不稳定的,也可以实现为稳定的,因此冒泡排序是一个稳定的排序。

好啦!本期 数据结构之八大排序(上)的学习之旅就到此结束啦!我们下一期再一起学习吧!

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

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

相关文章

SQL-自连接和分组

一.介绍 这是一道面试题&#xff0c;看似简单&#xff0c;其实还是有一定技巧的&#xff0c;分析一下可以复习一下SQL查询的一些重要概念。 二.问题 给定一个包含四列的员工表 IDNameSalaryManagerId 要求 获取经理姓名、每个经理的员工数量以及每个团队的总工资。 三.设…

Vscode ssh Could not establish connection to

错误表现 上午还能正常用vs code连接服务器看代码&#xff0c;中午吃个饭关闭vscode再重新打开输入密码后就提示 Could not establish connection to 然后我用终端敲ssh的命令连接&#xff0c;结果是能正常连接。 解决方法 踩坑1 网上直接搜Could not establish connectio…

前端表格控件:打造自动化报表的高效工具

摘要 在现代Web应用中&#xff0c;自动化报表的生成对于数据分析和业务决策至关重要。前端表格控件提供了一种直观且强大的方式&#xff0c;使得报表的创建、展示和交互变得更加容易。本文将探讨如何利用前端表格控件实现自动化报表的设计、生成和优化。 引言 自动化报表可以…

《Milvus Cloud向量数据库指南》——ChatGLM:从GLM-130B到GLM-4

ChatGLM:从GLM-130B到GLM-4的跨越:智谱AI在通用人工智能领域的深度探索与实践 在人工智能的浩瀚星空中,智谱AI如同一颗璀璨的新星,以其独特的技术视角和坚定的创新步伐,在通用人工智能(AGI)的征途上留下了深刻的足迹。技术生态总监贾伟在近期的一次分享中,不仅为我们描…

分布式日志分析系统--ELK

文章目录 ELK概述ELK主要特点ELK应用架构 Elasticsearch原理JSON格式倒排索引 ES与关系型数据库ES相关概念ES安装说明1.环境初始化2.优化系统资源限制配置3.编辑ES服务文件elasticsearch. yml 优化ELK集群安装脚本scp的使用集群安装成功 Shell命令API使用创建索引创建Type创建分…

Spring Cache常用注解

依赖代码如下&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency> 常用注解详解 1. Cacheable 作用&#xff1a;主要用于配置方法&#xff0c;使其…

真实体验!猫咪长肉选这些主食罐!猫生、希喂、黑夜传说详细测评

我的猫咖店铺开在高校附近&#xff0c;顾客以学生为主&#xff0c;也有很多养猫人士会到店里来&#xff0c;和我交流选粮经验。不少铲屎官都羡慕我店里的猫咪体格健壮&#xff0c;希望能介绍一些能够帮助猫咪长肉的主食罐头。那么今天我就选择了三款高肉含量的猫罐头进行测评&a…

【JLINK】J-link Commander

官方参考文档&#xff1a;J-Link Commander - SEGGER Wiki 一、运行 打开windows命令行窗口&#xff0c;找到有jlink.exe文件的地方&#xff0c;直接输入jlink.exe即可运行 二、常用命令 输入命令时候&#xff0c;大小写不影响 Command (long)Command (short)ExplanationExa…

【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(十四)-租云服务器及配环境、docker基本命令

主要介绍了租云服务器和docker配置、基本命令&#xff01;&#xff01;&#xff01; 文章目录 前言 一、云平台 二、租云服务器及安装docker 1.阿里云 2.安装docker 三、docker命令 将当前用户添加到docker用户组 镜像&#xff08;images&#xff09; 容器(container) 四、实战…

在linux运维中为什么第一道防线是云防火墙,而不是waf

在Linux运维和云计算环境中&#xff0c;第一道防线通常是云防火墙&#xff08;Cloud Firewall&#xff09;&#xff0c;而不是Web应用防火墙&#xff08;WAF&#xff09;&#xff0c;主要是因为云防火墙提供了更基础和广泛的网络层安全控制。以下是一些关键原因&#xff1a; 1…

vue elementui 上传视频 以及上传视频失败重新上传没反应的处理方法

<template><el-drawertitle"上传视频"size"50%":visible.sync"drawer":direction"direction"><div class"content"><div class"upload-box" v-if"!secondStep"><!--on-exce…

艾体宝干货 | 如何分析关键网络性能指标?持续接收样品试用申请!

网络性能是企业顺利运营的重要基础&#xff0c;而Allegro流量分析仪作为一款强大的网络性能分析工具&#xff0c;为企业提供了深入了解网络运行状况的途径。在本文中&#xff0c;我们将探讨如何利用Allegro 流量分析仪分析关键网络性能指标&#xff0c;以优化网络性能、提高安全…

AI来了,这4个方面,是我们普通人的赚钱机会

在2024年&#xff0c;AI不仅改变了我们的生活方式,更为我们带来了前所未有的赚钱机会。今天&#xff0c;让我们一起探索如何利用AI赚钱的几种方法。 通过AI做自由职业 还记得小时候大人们常说"一技在身,走遍天下"吗?在AI时代,这句话变得更加真实。自由职业意味着你…

Jeecgboot仪表盘设计器使用https时访问报错

问题 仪表盘设计器设计好后&#xff0c;Nginx配置域名发送https请求时&#xff0c;/drag/page/queryById、/drag/page/addVisitsNumber仍发送http请求。导致发送下面错误&#xff1a; 原因 仪表盘设计器里设计的页面是由后端生成返回给前端的&#xff0c;后端是根据后端服…

金融行业缓存建设历程

本文转载与中原银行分布式缓存平台建设历程及实践经验中原银行分布式缓存平台历经三代建设&#xff0c;实现了高效稳定智能的缓存服务&#xff0c;提升了系统性能与资源利用率&#xff0c;降低了运维难度&#xff0c;强有力的支撑金融业务。https://mp.weixin.qq.com/s/3NgLvAb…

不得不安利的程序员开发神器,太赞了!!

作为一名程序员&#xff0c;你是否常常为繁琐的后端服务而感到头疼&#xff1f;是否希望有一种工具可以帮你简化开发流程&#xff0c;让你专注于创意和功能开发&#xff1f;今天&#xff0c;我要向大家隆重推荐一款绝佳的开发神器——MemFire Cloud。它专为懒人开发者准备&…

Hive3:库操作常用语句

1、创建库 create database if not exists myhive;2、选择库 use myhive;3、查看当前选择的库 SELECT current_database();4、查看库详细信息 desc database myhive;可以查看数据文件在hdfs集群中的存储位置 5、创建库时制定hdfs的存储位置 create database myhive2 …

什么是 HTTP/3?HTTP/3 为何席卷全球?HTTP/3 中有什么新内容?为什么需要它?

超文本传输​​协议 ( HTTP ) 是互联网的基石&#xff0c;有助于加载网页、流式传输视频以及为您最喜爱的应用程序获取数据。 去年 &#xff0c;负责定义互联网技术的组织 互联网工程任务组 ( IETF )对该协议的新版本 HTTP/3 进行了标准化。自那时起&#xff0c;HTTP/3 和相关…

C语言分支结构作业

作业 输入你的身高和体重&#xff0c;测试你的健康状况。 计算bmi的值&#xff0c; bmi &#xff08;体重/身高的平方) 如果bmi 小于18.5&#xff0c;则显示“偏瘦&#xff0c;注意加强营养” 如果bmi 在18.5和23.9之间&#xff0c;则显示“体重指数良好&#xff0c;注意保持…

Linux基本功能

Linux 操作系统&#xff0c;作为开源社区的明星之一&#xff0c;以其稳定性、安全性和灵活性在全球范围内得到广泛应用。 1. 多用户和多任务支持 Linux 是一个真正的多用户系统&#xff0c;允许多个用户同时登录并在同一时间内运行多个程序。每个用户拥有自己的账户和权限&…