【数据结构趣味多】八大排序

news/2024/4/24 14:01:41/文章来源:https://blog.csdn.net/qq_65228171/article/details/129149117

目录

1.直接插入排序

基本思想

 代码实现:

直接插入排序的特性总结:

2.希尔排序

基本思想

代码实现 (递归实现)

希尔排序的特性总结

3.直接选择排序 

基本思想

代码实现: 

直接选择排序的特性总结

 4.堆排序

基本思路

代码实现 

堆排序的特性总结

 5.冒泡排序

基本思想

 代码实现:

冒泡排序的特性总结

 6.快速排序

基本思想

代码实现:

快速排序总结

 7.归并排序

基本思想:

代码实现: 

 归并排序总结


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

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

常见的排序算法:

1.直接插入排序

基本思想

直接插入排序是一种简单的插入排序法,其基本思想是
把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。也就是说当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移

 代码实现:

  1. 首先我们手中仅有一个数。
  2. 我们去出第二个数,大于手中的数就放到右边,小于就放到左边。
  3. 当数组中没有元素时,就代表排序结束。
public static void insertSort(int[] array) {for(int i = 1;i < array.length;i++) {//插入的数int tmp=array[i];int j=i-1;for(;j >= 0;j--) {//两种情况;//1.插入的数大于前面的数;2.插入的数小于前面的数//大小于决定排列顺序if(array[j]>tmp) {array[j+1]=array[j];}else {break;}}array[j+1]=tmp;}}

直接插入排序的特性总结:


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

2.希尔排序

基本思想

希尔排序是直接插入排序的优化版

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

代码实现 (递归实现)

  1. 将待排数据进行分组,分组之后,将各组的数据进行直接插入排序
  2. 第一组个数一般是数组长度的二倍,排序直到每一组只有一个元素。
  3. 仅剩一个元素时,再进行一次整体的插入排序来完成对数据的排序。
public static void shellSort(int[] array) {int gap=array.length;while (gap>1) {shell(array,gap);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) {//两种情况;//1.插入的数大于前面的数;2.插入的数小于前面的数//大小于决定排列顺序if(array[j]<tmp) {array[j+gap]=array[j];}else {break;}}array[j+gap]=tmp;}}

希尔排序的特性总结

1. 希尔排序是对直接插入排序的优化。
2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定。

3.直接选择排序 

基本思想

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

  • 在元素集合array[i]--array[n-1]中选择关键码最大(小)的数据元素
  • 若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换
  • 在剩余的array[i]--array[n-2](array[i+1]--array[n-1])集合中,重复上述步骤,直到集合剩余1个元素

代码实现: 

  1. 假设数组元素第一个元素是最小的元素。
  2. 对数组进行遍历,当遇到比minNub这个值小的元素,就将他赋值到minNub。
  3. 最终将minNub放到i下标处。
public static void selectSort(int array[]) {for (int i = 0; i < array.length; i++) {//存储最小值int minNub=array[i];//找最小值for (int j = i+1; j < array.length; j++) {if(minNub>array[j]) {int tmp=array[j];array[j]=minNub;minNub=tmp;}}//将最小值放到最前方array[i]=minNub;}}

直接选择排序的特性总结

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

 4.堆排序

基本思路

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

代码实现 

  1. 将根结点与最后一个叶子节点互换。
  2. 对堆进行向下调整,转换为大顶堆
  3. 此时,根结点是数组中最大的元素,将他与最后一个叶子节点进行互换。
  4. 循环上方1、2、3,最终得到的就是有序的数组
/*** 堆排序* @param array*/public static void heapSort(int[] array) {createBigHeap(array);int end = array.length-1;while (end > 0) {swap(array,0,end);shiftDown(array,0,end);end--;}}/*** 建一个大根堆* @param array*/private static void createBigHeap(int[] array) {for (int parent = (array.length-1-1)/2; parent >= 0 ; parent--) {shiftDown(array,parent,array.length);}}/*** 对建立的堆进行向下调整* @param array* @param parent* @param len*/private static void shiftDown(int[] array,int parent,int len) {int child = 2*parent+1;while (child < len) {if(child+1 < len && array[child] < array[child+1]) {child++;}if(array[child] > array[parent]) {swap(array,child,parent);parent = child;child = 2*parent+1;}else {break;}}}

堆排序的特性总结


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

 5.冒泡排序

基本思想

根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的
点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动

 代码实现:

  1. 拿到一个元素,对数组中的每一个元素进行比较,小于就不换,大于就换位置。
  2. 直到每个元素都进行互换后,就得到有序数组。
/*** 冒泡排序* @param array*/public static void bubbleSort(int[] array) {for (int i = 0; i < array.length-1; i++) {boolean flg=false;for (int j = 0; j < array.length-1-i; j++) {if(array[j]>array[j+1]) {swap(array,j,j+1);flg=true;}}if(flg==false) {return;}}}

冒泡排序的特性总结


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

 6.快速排序

基本思想

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。
 

代码实现:

  1. 找基准值,这个基准值是随机的。
  2. 将所有的小于基准值的数都放到基准值的左边,将所有的大于基准值的数都放到基准值的右边。
  3. 然后将左边和右边的排的数再看出一个数组再次进行上方1、2操作,知道数组中的元素只剩一个,这时待排数据就有序了。
/**** 快速排序(递归实现)* 挖坑法* @param array*/public static void quickSort1(int[] array) {quick(array,0,array.length-1);}/**** 通过递归对左数和右树排序* @param array* @param start* @param end*/private static void quick(int[] array,int start,int end) {if(start>=end) {return;}int pivot=partition(array,start,end);//左树排序quick(array,start,pivot-1);//右树排序quick(array,pivot+1,end);}/**** 找基准值* @param array* @param left* @param right* @return*/private static int partition(int[] array,int left,int right){int tmp=array[left];while (left<right) {//找比tmp小的值while (left<right && array[right]>=tmp) {right--;}array[left]=array[right];//找比tmp大的值while (left<right && array[left]<=tmp) {left++;}array[right]=array[left];}//将最后一个坑补上array[left]=tmp;return left;}

快速排序总结

1. 快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序
2. 时间复杂度:O(N*logN)

3. 空间复杂度:O(logN)
4. 稳定性:不稳定

 7.归并排序

基本思想:

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
 

代码实现: 

/*** 归并排序* @param array*/public static void mergeSort(int[] array, int left, int right) {if (left < right) {int mid = left + ((right - left) >> 1);mergeSort(array,left,mid);mergeSort(array,mid+1,right);merge(array,left,mid,right);}}//归并public static void merge(int[] arr,int left, int mid, int right) {//第一步,定义一个新的临时数组int[] tempar = new int[right -left + 1];int temp1 = left, temp2 = mid + 1;int index = 0;//对应第二步,比较每个指针指向的值,小的存入大集合while (temp1 <= mid && temp2 <= right) {if (arr[temp1] <= arr[temp2]) {tempar[index++] = arr[temp1++];} else {tempar[index++] = arr[temp2++];}}//对应第三步,将某一小集合的剩余元素存到大集合中if (temp1 <= mid) System.arraycopy(arr, temp1, tempar, index, mid - temp1 + 1);if (temp2 <= right) System.arraycopy(arr, temp2, tempar, index, right -temp2 + 1);     //将大集合的元素复制回原数组System.arraycopy(tempar,0,arr,0+left,right-left+1);}

 归并排序总结


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

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

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

相关文章

Springboot 全局异常处理类

全局异常处理 在开发过程中&#xff0c;不管是Dao、Servie、Controller,层都有可能发生异常&#xff0c;对于异常处理&#xff0c;通常是try&#xff0d;catch或者直接throw&#xff0c;这会让try&#xff0d;catch的代码在代码中任意出现&#xff0c;系统的代码耦合度高&…

深入Spring底层透析bean生命周期及循环引用的醍醐灌顶篇

目录前言一.Bean的生命周期1.1 Bean的实例化阶段1.2 Bean的初始化阶段&#xff08;重点&#xff09;1.3 Bean的完成阶段二.循环引用问题(面试常问题&#xff09;三.Spring的三级缓存&#xff08;重点来了&#xff09;四.完整的Spring IoC整体总结前言 本篇是接着bean的创建基本…

2023/02/21 事件循环-eventloop 宏任务 微任务 讲解

1 JS是单线程 js是单线程的。也就是说&#xff0c;同一个时间只能做一件事。作为浏览器脚本语言&#xff0c;与它的用途有关。JavaScript的主要用途是和用户互动&#xff0c;以及操作DOM&#xff0c;这决定了它只能是单线程。 js是单线程的。也就是说&#xff0c;同一个时间只…

非常优秀的网站设计案例,设计师必备

厚积才能薄发&#xff0c;一个优秀的设计师的天性一定是想要获得更多网站设计灵感&#xff0c;擅于为新项目寻找创意切入点、搜索设计参考资源、最新的设计趋势。今天为大家带来了一组免费可商用的网站设计案例&#xff0c;通过这些网站设计案例&#xff0c;你可以获得&#xf…

CF707C Pythagorean Triples 题解

CF707C Pythagorean Triples 题解题目链接字面描述题面翻译题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1样例 #2样例输入 #2样例输出 #2样例 #3样例输入 #3样例输出 #3样例 #4样例输入 #4样例输出 #4样例 #5样例输入 #5样例输出 #5提示思路代码实现题目 链接 http…

华为OD机试 - 最短耗时(C++) | 附带编码思路 【2023】

刷算法题之前必看 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:https://blog.csdn.net/hihell/category_12199283.html 华为OD详细说明:https://dream.blog.csdn.net/article/details/128980730 华为OD机试题…

算法笔记(十一)—— 并查集、KMP

并查集 支持集合快速合并 所有数据生成各自的集合&#xff0c;需要提供查询两个两素是不是属于一个集合&#xff0c;和集合合并操作&#xff0c;并查集能够在常数时间级别上对两个操作进行实现 1. 构造结构&#xff08;数据指针&#xff09;&#xff0c;将自己的指针指向自己…

事件流、事件冒泡、阻止冒泡

1、事件流 2、事件冒泡&#xff1a;从小到大 概念&#xff1a; 当一个元素的事件被触发时&#xff0c;同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒泡 <style> .father{width: 300px;height: 300px;background-color: pink; } .son{width:…

Zookeeper框架

Zookeeper框架概述 1.Zookeeper介绍 Zookeeper&#xff08;以下简称ZK&#xff09;是用来管理和协调其他框架的&#xff0c;很多框架需要依赖ZK&#xff08;例如Hadoop-HA&#xff0c;Kafka&#xff0c;HBase等&#xff09;ZK本身也是一个集群ZK本身也可以存数据(一般保存配置…

koa中间件的实现原理

koa中间件的实现原理如何&#xff1f;先来看一个例子。koa的执行顺序是这样的&#xff1a;const middleware asyncfunction (ctx, next) {console.log(1)await next()console.log(6) }const middleware2 asyncfunction (ctx, next) {console.log(2)await next()console.log(5…

LeetCode 535. TinyURL 的加密与解密

TinyURL 是一种 URL 简化服务&#xff0c; 比如&#xff1a;当你输入一个 URL https://leetcode.com/problems/design-tinyurl 时&#xff0c;它将返回一个简化的URL http://tinyurl.com/4e9iAk 。请你设计一个类来加密与解密 TinyURL 。 加密和解密算法如何设计和运作是没有限…

产品新说 | 指标异常?怎么做能更好配合业务变化(一)

​ 背景&#xff1a; 企业业务运营的平稳&#xff0c;常常要依靠智能运维在后方保驾护航。熟悉运维的肯定都知道&#xff0c;在智能运维中有一环是通过监控指标来判断系统、云、业务应用、网络设备等运行的是否健康&#xff0c;以便及时排障维稳后台。在指标异常检测中&#xf…

读书笔记//来自公众号(2)

非常喜欢阅读同行的文章&#xff0c;彷佛进行一场隔空交流。大家都是数据分析师&#xff0c;有许多共鸣&#xff1b;了解数据分析在不同行业的应用&#xff0c;往往很有收获。 这位朋友在零售行业、工业物联网、汽车互联网、2G电商等做个数据分析&#xff0c;有10多工作经验。…

opencv在windows下环境搭建遇到问题

文章目录debug模式下执行到cv::imshow()报内存异常qt配置opencv环境出现的问题debug模式下执行到cv::imshow()报内存异常 原因是&#xff1a;在添加静态库的时候opencv_world460.lib和opencv_world460d.lib都导入了。 在debug模式下只能导入opencv_world460d.lib动态库&#xf…

OpenGL 渲染管线与显卡可执行程序

渲染管线的六个步骤 OpenGL 渲染管线的六个步骤&#xff0c;从指定几何图元到帧缓冲区写入像素&#xff0c;图像就被 OpenGL 引擎一步步地渲染到屏幕&#xff08;FBO&#xff09;上去了。 指定几何对象 OpenGL 引擎会根据开发者的指令去绘制几何图元。OpenGL&#xff08;ES&…

IMX6ULL学习笔记(17)——工程管理

一、简介 之前我们把所有源码文件放在一个文件夹下。 这样做存在两个主要问题&#xff0c;第一&#xff0c;代码存放混乱不易阅读。第二&#xff0c;程序可移植性差。如果工程源文件达到几十、甚至数百个的时候&#xff0c;这样一股脑全部放到根目录下就会使工程显得混乱不堪。…

[JavaEE系列] 详解面试中HTTP协议HTTPS协议

文章目录HTTP不安全HTTPS中的加密算法对称加密非对称加密混合加密HTTPS中的摘要算法HTTPS中的数字证书SSL /TLS握手TCP建立连接&#xff08;三次握手&#xff09;三次握手中常见的面试题&#xff1a;TCP断开连接&#xff08;四次挥手&#xff09;四次挥手中常见的面试题&#x…

前端页面开发模块组织结构

模块组织 任何超过 1000 行的 CSS 代码,你都曾经历过这样的体验: 这个 class 到底是什么意思呢?这个 class 在哪里被使用呢?如果我创建一个 xxoo class,会造成冲突吗?Reasonable System for CSS Stylesheet Structure 的目标就是解决以上问题,它不是一个框架,而是通过…

2.5|1.3 操作系统与嵌入式操作系统概述

CPU是计算机系统的心脏&#xff0c;操作系统是计算机系统的大脑。半个世纪以来操作系统这门软件科学吸引了世界上一大群最热情、最有智慧的杰出人材&#xff0c;集中了人类现代创造性思维活动的精髓。操作系统是软件世界的万花筒、世博会&#xff0c;是软件王国中的一顶璀璨的皇…

十二、Django表单

表单 在之前的案例中&#xff0c;每次我们需要提交表单数据的时候。我们都需要去手动编辑html表单&#xff0c;根据不同的字段&#xff0c;字段名&#xff0c;进行编码。做了很多重复的部分&#xff0c;所以django提供了一个专门用来处理表单的类&#xff0c;django.forms.For…