直接插入排序 希尔排序 选择排序 堆排序

目录

一. 排序的概念及应用

1.1 排序的概念

1.2 常见的排序算法

二. 常见排序算法的实现(从小到大排序)

2.1 插入排序

2.1.1基本思想:

2.1.2 直接插入排序

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

2.2 选择排序

2.2.1基本思想:

2.2.2 直接选择排序:

2.2.3 堆排序


一. 排序的概念及应用

1.1 排序的概念

排序 :所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
稳定性 :假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j] ,且 r[i]r[j] 之前,而在排序后的序列中, r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。

 

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

1.2 常见的排序算法

二. 常见排序算法的实现(从小到大排序)

2.1 插入排序

2.1.1基本思想:

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

2.1.2 直接插入排序

当插入第 i(i>=1) 个元素时,前面的 array[0],array[1],…,array[i-1] 已经排好序,此时用 array[i] 的排序码与 array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将 array[i] 插入,原来位置上的元素顺序后移
思路:
  1. 从第二个元素i = 2时开始插入, 将第i个元素放在tmp中, 设j = i-1
  2. 如果小标为j的值大于tmp, 说明tmp要插在j前面, 所以arr[j+1]= arr[j], 将j所指的值向后移动, 给i让出位置,  j继续向前移动
  3.  但如果j所指的值小于tmp, 则说明j的值的位置不需要变化, 说明tmp找到了自己的位置, 直接将arr[j+1] = tmp , 因为前面的数据已经有序, 所以直接跳出循环即可, 前面的元素不用比较, 一定是小于tmp的
  4. 如果循环走完了, 即j = -1了, 说明tmp是最小的一个数据, 直接放在数组的最前面即可, 前面已经腾出了位置,即 arr[j+1] = tmp
  5.  继续循环上述步骤, 指到将数组的元素全部插入
代码:
 public static void insertSort(int[] arr){for (int i = 1; i <arr.length ; i++) {int tmp = arr[i];int j = i-1;for ( ; j >= 0; j--) {if(arr[j] > tmp){arr[j+1] = arr[j];}else{//arr[j+1] = tmp;break;}}arr[j+1] = tmp;}}

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

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

希尔排序法又称缩小增量法。希尔排序法的基本思想是: 先选定一个整数gap,把待排序文件中所有记录分成多个组, 所有距离为gap的记录分在同一组内,并对每一组内的记录进行排序。然后,缩小gap的值,重复上述分组和排序的工作。当到达gap  =1 时,所有记录在统一组内排好序
思路:
  1. 首先我们要分组gap, 第一次分组, 分成数组长度的一半, 接下来分组的方式有很多, 可以gap = gap/2, 可以gap = gap/3 +1 , 等等, 现在没有任何理论可以证明哪种分组最好, 这里我们使用gap= gap/2
  2. 分组分到所有的数据为一组, 即gap = 1时,停止
  3. 每一次分组, 我们都要对组内的元素进行排序, 我们选择的方法时直接插入排序, 可参考上述
  4. 但需要注意的是, 如何找到组内的元素, 我们可以将i设成gap, 很巧妙的是, i此时正好是每个组内的第二个元素, 那么前面的元素, 即 j 就是i-gap, j的移动单位就为gap, i每次向后走1, 可以到下一个组进行排序, 当i走到数组的最后时, 每个组内的元素都是有序的
代码:
public static void shellSort(int[] arr){int gap = arr.length/2;while(gap!= 1){gap = gap/2;shell(arr, gap);}}private static void shell(int[] arr,int gap){for (int i = gap; i < arr.length; i++) {int tmp = arr[i];int j = i-gap;for (; j>=0; j-=gap) {if(arr[j] > tmp){arr[j+gap] = arr[j];}else{break;}}arr[j+gap] = tmp;}}
希尔排序的特性总结:
  •  希尔排序是对直接插入排序的优化。
  •  gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
  •  希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定
  •  稳定性:不稳定

2.2 选择排序

2.2.1基本思想:

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

2.2.2 直接选择排序:

在元素集合 array[i]--array[n-1] 中选择关键码最大 ( ) 的数据元素, 若它不是这组元素中的最后一个( 第一个 ) 元素,则将它与这组元素中的最后一个(第一个)元素交换在剩余的array[i]--array[n-2] array[i+1]--array[n-1] )集合中,重复上述步骤,直到集合剩余 1 个元素
思路1:
  1. 设i=0, 将i存放在minIndex里, 假设i是最小值的下标
  2. 遍历i后面的元素, 如果有比minIndex下标的值小的数据, 则更改minIndex的值, 即minIndex = j
  3. 遍历完成后, minIndex里面存放的是最小数据的值, 接着交换i和minIndex下标的值

注意: 此时不能写arr[i] = arr[minIndex], 如果这样写, 假设i下标存放的不是最小值, 那么用minIndex下标的值将i下标的值覆盖, 则会丢失i下标的值

     4. 接着i++, 循环上述步骤, 直到遍历完整个数组

代码:
public static void selectSort(int[] arr){for (int i = 0; i < arr.length; i++) {int minIndex = i;for (int j = i+1; j < arr.length; j++) {if(arr[j] < arr[minIndex]){minIndex = j;}}swap(arr,i,minIndex);}}private static void swap(int[] arr,int i,int j){int tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}

思路2:

  1. 相当于思路1的优化, 遍历一遍数组可以同时找出最小值和最大值
  2. left 和 right相当于思路1中i的作用
  3. i 相当于思路1中j的作用, 用来遍历数组(注意:此时要从left开始遍历, 而不是left+1, 因为有可能left值就是最大值, 如果从left+1开始, 则最大值找不到)
  4. minIndex 和 maxIndex作用同样是存放最小值下标和最大值下标

代码:

public static void selectSort2(int[] arr){int left = 0;int right = arr.length -1;while(left< right){for (int i = left; i <= right ; i++) {int minIndex = left;int maxIndex = right;if(arr[i] < arr[minIndex]){minIndex = i;}if(arr[i] > arr[maxIndex]){maxIndex = i;}swap(arr,left,minIndex);swap(arr,right,maxIndex);left++;right--;}}}private static void swap(int[] arr,int i,int j){int tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}
直接选择排序的特性总结
  •  直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
  •  时间复杂度:O(N^2)
  •  空间复杂度:O(1)
  •  稳定性:不稳定

2.2.3 堆排序

堆排序 (Heapsort) 是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。
思路:
  1. 建立大根堆
  2. 交换堆顶元素和最后一个元素end, 这样就找到的最大的数放在最后
  3. 向下调整成大根堆, 但不算最后一个结点, 因为最后一个结点已经在应该的位置, 这样堆顶元素又变成了除最后一个元素外最大的元素
  4. 重复前两个步骤, 交换倒数第二个元素end--和堆顶元素, 这样就找到了倒数第二大的元素, 以此类推, 直到end==0时, 说明已经全部有序, 输出即可
代码:
public static void heapSort(int[] arr){createHeap(arr);int end = arr.length-1;while(end > 0){swap(arr,0,end);siftDown(arr,0,end);end--;}}private static void createHeap(int[] arr){for(int parent = (arr.length-1-1)/2;parent >0;parent--){siftDown(arr,parent,arr.length);}}private static void siftDown(int[] arr, int parent, int len){int child = (parent*2)+1;while(child < len){if(child +1 < len && arr[child+1]>arr[child]){child = child+1;}if(arr[child] > arr[parent]){swap(arr,child,parent);parent = child;child = (parent*2)+1;}else{break;}}}
【堆 排序的特性总结
  •  堆排序使用堆来选数,效率就高了很多。
  •  时间复杂度:O(N*logN)
  •  空间复杂度:O(1)
  •  稳定性:不稳定
未完待续...

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

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

相关文章

动态规划——线性dp

数字三角形 // 从上到下 #include <iostream> #include <algorithm> using namespace std; const int N 510, INF 1e9; int n; int a[N][N]; int f[N][N];int main() {scanf("%d", &n);for (int i 1; i < n; i )for (int j 1; j < i; j …

计算机组成原理 CPU组成与机器指令执行实验

一、实验目的 (1)将微程序控制器同执行部件( 整个数据通路)联机&#xff0c;组成一台模型计算机; (2)用微程序控制器控制模型机数据通路; (3)通过CPU运行九条机器指令(排除中断指令)组成的简单程序&#xff0c;掌握机器指令与微指令的关系&#xff0c;牢固建立计算机的整机概…

深度学习pytorch——2D函数优化实例(持续更新)

课程&#xff1a;课时46 优化问题实战_哔哩哔哩_bilibili 这就是我们今天要求的2D函数&#xff1a; 下图是使用python绘制出来的图像&#xff1a; 但是可以看出有4个最小值&#xff0c;但是还是不够直观&#xff0c;还是看课程里面给的比较好&#xff0c;蓝色是最低点位置&am…

Python 全栈系列236 rabbit_agent搭建

说明 通过rabbit_agent, 以接口方式实现对队列的标准操作&#xff0c;将pika包在微服务内&#xff0c;而不必在太多地方重复的去写。至少在服务端发布消息时&#xff0c;不必再去考虑这些问题。 在分布式任务的情况下&#xff0c;客户端本身会启动一个持续监听队列的客户端服…

Django(一)- 环境搭建和快速入门

一、搭建环境 1、创建Python虚拟环境 (base) C:\Users\35351>conda create -n django_study python3.9 2、安装Django (django_study) C:\Users\35351>pip install Django >> 查看安装版本 (django_study) C:\Users\35351>python -m django --version 3、安…

数据分析与挖掘

数据起源&#xff1a; 规模庞大&#xff0c;结构复杂&#xff0c;难以通过现有商业工具和技术在可容忍的时间内获取、管理和处理的数据集。具有5V特性&#xff1a;数量&#xff08;Volume&#xff09;&#xff1a;数据量大、多样性&#xff08;Variety&#xff09;&#xff1a…

CSS(二)

一、CSS 的复合选择器 1.1 什么是复合选择器 在 CSS 中&#xff0c;可以根据选择器的类型把选择器分为基础选择器和复合选择器&#xff0c;复合选择器是建立在基础选择器之上&#xff0c;对基本选择器进行组合形成的。 复合选择器可以更准确、更高效的选择目标元素&#xff…

OC对象 - 关联对象(如何给分类添加成员变量)

文章目录 OC对象 - 关联对象&#xff08;如何给分类添加成员变量&#xff09;1. 基本使用1.1 提供的API1.1.1 添加关联对象1.1.2 获得关联对象1.1.3 移除所有关联对象1.1.3 修饰符 1.2 使用方法1.2 Key的常见用法1.2.1 使用的get方法的selecor作为key1.2.2 使用指针的地址作为k…

LeetCode每日一题——移除链表元素

移除链表元素OJ链接&#xff1a;203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 思路&#xff1a; 这与之前的移除元素的题目很相似&#xff0c;那么我们同样可以用类似的做法&#xff08;双指针&#xff09;进行解题。但是这是一个链表删除&a…

树状数组原理和代码

树状数组 求下标的对应 求i管着的下标的范围 方法&#xff1a;拆掉最右侧的1然后1 到你自己 query sum 1-i的和 拆掉最右侧的1 再把下一个数值吸收到sum 重复这个过程直到全变0为止 add 方法&#xff1a;加上最右侧的1 到上限为止 lowbit方法 单点增加范围查询模板 #inc…

no main manifest attribute, in xxx.jar

找不到主类&#xff0c;如果是maven 项目&#xff0c;在pom.xml 指定主类 <mainClass>com.example.demo.Demo2Application</mainClass>还是不行的话&#xff0c;把 <skip>true</skip>去掉

nodejs+vue高校师资管理系统python-flask-django-php

快速发展的社会中&#xff0c;人们的生活水平都在提高&#xff0c;生活节奏也在逐渐加快。为了节省时间和提高工作效率&#xff0c;越来越多的人选择利用互联网进行线上打理各种事务&#xff0c;然后线上管理系统也就相继涌现。与此同时&#xff0c;人们开始接受方便的生活方式…

从FasterTransformer源码解读开始了解大模型(1.0)了解FasterTransformer

从FasterTransformer源码解读开始了解大模型&#xff08;1.0&#xff09;了解FasterTransformer 写在前面的话 最近的一年时间真是令人感慨&#xff0c;换了个工作方向&#xff0c;学了些深度算子开发相关知识&#xff0c;工作也转到对LLM的学习和开发了。入行不算深&#xf…

谷粒商城——缓存的概念

1. 使用缓存的好处&#xff1a;减少数据库的访问频率&#xff0c;提高用户获取数据的速度。 2. 什么样的数据适合存储到缓存中&#xff1f; ①及时性、数据一致性要求不高的数据&#xff0c;例如物流信息、商品类目信息 ②访问量大更新频率不高的数据(读多、写少) 3. 读模式…

加密技术概述

传输数据时的四个问题 窃听 数字加密 假冒 消息认证或数字签名 篡改 消息认证码或数字签名 事后否认 数字签名 加密技术 将数据变成第三者的计算机无法理解的形式&#xff0c;然后再将其恢复成原本数据的一系列操作就是加密技术。 哈希函数 哈希函数可以把给定的数据转…

设计模式之状态模式(一)

设计模式专栏&#xff1a; http://t.csdnimg.cn/4Mt4u 目录 1.概述 2.结构 3.实现 4.总结 1.概述 状态模式( State Pattern)也称为状态机模式( State Machine pattern), 是允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类, 属于行为型模式。 在状…

Vue3+echarts绘制世界地图

先放效果图 之前所查找的资料都没有讲清楚如何引入地图文件并绘制地图&#xff0c;下面做一个记录。 首先下载对应的地图json文件&#xff0c;这里可以参考我的这篇文章&#xff0c;提供了下载地址&#xff1a;记录echarts各种地图json文件下载地址-CSDN博客 第二步&#xff…

笔记本和台式机主板内部结构分析

笔记本和态势机主板内存接口以及配件安装位置 笔记本主板 1 以thinkpad L-490为例,使用拆机小工具拆机&#xff0c;打开后面板&#xff0c;内部结构示意图如下 台式机主板 以技嘉-B660M-AORUS-PRO-AX型号主板为例 笔记本电脑和台式机电脑的相同之处 CPU&#xff1a;笔记本…

【boost_search搜索引擎】1.获取数据源

boost搜索引擎 1、项目介绍2、获取数据源 1、项目介绍 boost_search项目和百度那种不一样&#xff0c;百度是全站搜索&#xff0c;而boost_search是一个站内搜索。而项目的宏观上实现思路就如同图上的思路。 2、获取数据源 我们要实现一个站内搜索&#xff0c;我们就要有这…

Rust 程序设计语言学习——结构体

结构体和元组类似&#xff0c;它们都包含多个相关的值。和元组一样&#xff0c;结构体的每一部分可以是不同类型。但不同于元组&#xff0c;结构体需要命名各部分数据以便能清楚的表明其值的意义。由于有了这些名字&#xff0c;结构体比元组更灵活&#xff1a;不需要依赖顺序来…