数据结构中的七大排序(Java实现)

目录

一、直接插入排序

二、希尔排序

三、直接选择排序

四、堆排序

五、冒泡排序

六、快速排序

七、归并排序


一、直接插入排序

思想:

             定义i下标之前的元素全部已经有序,遍历一遍要排序的数组,把i下标前的元素全部进行排序,当遍历玩这个数组后,就已经排好序了。

代码如下:

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--) {if(array[j] > tmp) {array[j + 1] = array[j];} else {break;}}array[j + 1] = tmp;}}

代码解析

                要使i下标之前的元素都有序,定义一个j下标,为i - 1;再用tmp记录i下标的位置只要j下标元素比tmp大,j下标的元素就要放到j+1下标,最后j走完后,再把最小的tmp放在j+1位置。

时间复杂度、空间复杂度、稳定性:

        时间:O(n^2)

        空间:O(1)

        稳定性:稳定


二、希尔排序

思想:

                希尔排序也称缩小增量排序,就是分次去进行排序越排到后面就会越有序每次间隔是gap,然后逐渐缩小,到最后间隔为0,也就是用我们的直接插入排序,数组越有序,速度也会越快。那么就很简单了,我们只需改一下直接插入排序每次排序的间隔,把他们分成不同组进行排序,直到最后间隔为0,就只剩一组,然后也是用直接插入排序,做最后一次排序,排完就是有序的了。

图式例:

代码如下:

public static void shellSort(int[] array) {int gap = array.length / 2;while (gap >= 1) {gap /= 2;shell(array, gap);}}public 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;}}

时间复杂度、空间复杂度、稳定性:

        时间:n^1.3(严蔚敏) 因为gap取值方式不同,计算出来的时间复杂度也会不同

        空间:O(1)

        稳定性:不稳定


三、直接选择排序

思想:

                直接选择排序也是和直接插入排序差不多,定义i下标前的元素全部都有序,不过排序的方式不同,它是拿i下标前的元素和i下标后的元素进行比较找到下标最小的元素把最小元素放进i下标中,同时这个i下标元素放到被这个最小下标位置。

代码实现:

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;}}//走完这里,找到最小元素的下标minIndex//交换int tmp = array[i];array[i] = array[minIndex];array[minIndex] = tmp;}}

时间复杂度、空间复杂度、稳定性:

        时间:O(n^2)

        空间:O(1)

        稳定性:不稳定


四、堆排序

思想:

                堆其实就是完全二叉树,下标是从上到下,从左到右依次递增,要把堆排序成升序,就要把他先变成大根堆,每次出大根堆的顶点,把顶点放在最后一个节点,然后再向下调整一次第二次把大根堆的顶点放到倒数第二个位置,依次往后推。

代码实现:

//堆排序public static void heapSort(int[] array) {//先转换成大根堆createHeap(array);//开始换,然后向下转换for (int i = array.length - 1; i > 0 ; i--) {//i下标的节点和堆顶交换int tmp = array[0];array[0] = array[i];array[i] = tmp;//向下调整siftDown(array,0, i);}}
//创建大根堆public static void createHeap(int[] array) {//从最后一个父节点开始向下调整,下标依次往前减//parent = (child - 1) / 2; 左:child = parent * 2 + 1 右:child = parent * 2 + 2for (int i = (array.length - 1 - 1) / 2; i >= 0 ; i--) {siftDown(array, i, array.length);}}//向下调整public static void siftDown(int[] array, int parent, int length) {//定义一个child为该父节点的左孩子int child = parent * 2 + 1;while (child < length) {//比较改父节点的左右孩子,把值最大的孩子作为交换节点if(array[child] < array[child + 1]) {child += 1;}//比较父节点和孩子节点大小if(array[parent] < array[child]) {//交换int tmp = array[parent];array[parent] = array[child];array[child] = tmp;parent = child;child = child * 2 + 1;} else {break;}}}

时间复杂度、空间复杂度、稳定性:

        时间复杂度:O(NlogN)

        空间复杂度:O(1)

        稳定性:不稳定

五、冒泡排序

思想:

                冒泡排序的思想很简单,就是第一次把最大的值放到数组最后一个下标中,再把第二大的元素放到数组倒数第二个下标中,依次类推

代码实现:

 //冒泡排序public static void bubbleSort(int[] array) {for (int i = 0; i < array.length; i++) {boolean flag = false;//标记for (int j = 0; j < array.length - 1 - i; j++) {if(array[j] > array[j + 1]) {//交换int tmp =array[j];array[j] = array[j + 1];array[j + 1] = tmp;flag = true;}}if(!flag) {break;}}}

时间复杂度、空间复杂度、稳定性:

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

        空间复杂度:O(1)

        稳定性:稳定


六、快速排序

思想:

                使用递归思想也可以采用非递归思想把一组数据划分成两部分左边都小于该下标元素,右边都大于该下标元素,再在左边去找元素划分,右边元素去划分,依次往后推,直到左右两边都没有元素可以划分了,就是只剩一个元素了,这时候往回倒,就有序了

代码实现:

public static void quickSort(int[] array) {int left = 0;int right = array.length - 1;quick(array, left, right);}public 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);}public static int partition(int[] array, int left, int right) {//找到一个下标元素,左边都比这个下标元素小,右边都比这个下标元素大,并且还要返回这个下标//记录下标为0的值,放在tmp中int tmp = array[0];while (left < right) {//先走右边if(left < right && array[right] >= tmp) {right--;}if(left < right && array[left] <= tmp) {left++;}//左下标的值大于tmp,右下标的值小于tmp,这两个下标值交换int newTmp = array[left];array[left] = array[right];array[right] = newTmp;}//走到这,left和right相遇了,left下标的值和tmp交换,并且返回这个位置的下标int newTmp = tmp;tmp = array[left];array[left] = newTmp;return left;}

时间复杂度、空间复杂度、稳定性:

        时间复杂度:O(NlogN)

        空间复杂度:O(logN~N)

        稳定性:不稳定


七、归并排序

思想:

                将一组数组分割成左右两部分,和快速排序找出的中件位置不同,归并的中间位置是最左和最右下标相加再除2(left+right)/ 2,运用的也是递归思想(也可以采用非递归思想,采用分治法,一直找到最左边进行排序,然后再找最右边进行排序,再往归回整体排序(合并)合并的时候是放在一个临时数组中,再把这个临时数组拷贝到原数组,下标要对应

代码实现:

public static void mergeSort(int[] array) {int start = 0;int end = array.length - 1;mergeSortFunc(array, start, end);}//套壳public static void mergeSortFunc(int[] array, int start, int end) {//递归结束标志if(start >= end) {return;}//求出中间节点位置int mid = (start + end) / 2;//左边mergeSortFunc(array, start, mid);//右边mergeSortFunc(array, mid + 1, end);//合并merge(array, start, mid, end);}//合并public static void merge(int[] array, int left, int mid, int right) {//定义mid两边的左右下标int s1 = left;int e1 = mid;int s2 = mid + 1;int e2 = right;//定义一个新的数组,存放array排序完后的数组int[] tmpArray = new int[right - left - 1];int k = 0;while (s1 <= e1 && s2 <= e2) {//比较左右两边s1和s2的值if(array[s1] < array[s2]) {tmpArray[k++] = array[s1++];} else {tmpArray[k++] = array[s2]++;}if(s1 <= e1) {tmpArray[k++] = array[s1++];}if(s2 <= e2) {tmpArray[k++] = array[s2++];}}//拷贝到原数组for (int i = 0; i < tmpArray.length; i++) {array[left + i] = tmpArray[i];}}

时间复杂度、空间复杂度、稳定性:

        时间复杂度:O(NlogN)

        空间复杂度:O(N)

        稳定性:不稳定


都看到这了,给个免费的赞呗,谢谢谢谢!!!

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

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

相关文章

ArGIS Engine专题(15)之GP模型在地图服务与地图服务之间实现叠置分析

前一篇文章已经介绍过导入要素范围与地图服务的叠加分析,相当于单要素与多要素之间的分析,这篇文章介绍地图服务与地图服务之间的叠加分析,即是多要素有多要素之间的相交分析,功能基本类似。 一、结果预览 二、需求简介 以下是一些常见的业务场景: (1)空间规划和土地…

电脑技巧:27个Office使用小技巧,值得收藏

目录 一、Word 二、EXCEL 三、附文&#xff1a;Word和Excel快捷键 我们中的绝大部分人都使用微软的Office&#xff0c;但是我们是否都了解如何能够最有效地使用它&#xff1f;我们在这里列举了一些关于使用Word和Excel的窍门。 我们使用最多的软件可能就是办公软件了——字…

思辨:移动开发的未来在哪?

前段时间在知乎看到关于移动开发未来的问题&#xff0c;就尝试回答了一下&#xff0c;也触发了我对移动开发未来的思考。 什么是移动开发&#xff1f; 我们口中说的移动开发是什么&#xff0c;从广义和狭义的角度分别来看下&#xff1a; 从广义角度来看&#xff0c;移动开发是…

docker-rabbitmq 安装依赖

出现的问题如下: channel error; protocol method: #method(reply-code404, reply-textNOT_FOUND - no channel error&#xff1b; protocol method: #method&#xff1c;channel.close&#xff1e;(reply-code404, reply-textNOT_FOUND - no 查看rabbitmq 客户端是否存在如…

Kubernetes - 一键安装部署 K8S(附:Kubernetes Dashboard)

问题描述 不知道大伙是如何安装 K8s&#xff0c;特别还是集群的时候&#xff0c;我上一次安装搭建的时候&#xff0c;那个恶心到我了&#xff0c;真的是一步一个脚印走完整个搭建流程&#xff0c;爬了不少坑。 于是&#xff0c;才有了今天的文章&#xff0c;到底有没有可以一…

Kafka快速入门(最新版3.6.0)

文章目录 一、初识MQ1.1 什么是MQ1.2 同步和异步通讯1.1.1 同步通讯1.1.2 异步通讯 1.3 技术对比1.4 MQ的两种模式 二、初识Kafka2.1 Kafka的使用场景2.2 Kafka基本概念2.3 Topic与Partition 三、Kafka基本使用3.1 部署前的准备3.2 启动kafka服务器3.3 Kafka核心概念之Topic3.4…

出差学小白知识No6:LD_PRELOAD变量路径不对找不到库文件

交叉编译的时候出现以下问题&#xff0c;显示LD_PRELOAD变量找不到路劲 首先先查看一下LD_PRELOAD的路径&#xff1a;echo $LD_PRELOAD 如果输出一大串&#xff0c;那么先进行清空&#xff1a;unset LD_PRELOAD 重新给LD_PRELOAD进行赋值他的路径和库文件&#xff1a; expor…

自然语言处理---RNN经典案例之构建人名分类器

1 案例介绍 关于人名分类问题&#xff1a;以一个人名为输入, 使用模型帮助判断它最有可能是来自哪一个国家的人名&#xff0c;这在某些国际化公司的业务中具有重要意义&#xff0c;在用户注册过程中&#xff0c;会根据用户填写的名字直接给他分配可能的国家或地区选项&#xff…

【第三天】C++类和对象进阶指南:从堆区空间操作到友元的深度掌握

一、new和delete 堆区空间操作 1、new和delete操作基本类型的空间 new与C语言中malloc、delete和C语言中free 作用基本相同 区别&#xff1a; new 不用强制类型转换 new在申请空间的时候可以 初始化空间内容 2、 new申请基本类型的数组 3、new和delete操作类的空间 4、new申请…

为什么需要it企业知识库?it企业知识库能带来什么?

在企业运营过程中&#xff0c;会产生大量的经营数据、管理规范、资料和文档等数据&#xff0c;但这些数据的产生时间和空间碎片化&#xff0c;数据来源和结构多种多样&#xff0c;信息关系也较为复杂。 it企业知识库 正是因为这些问题的存在&#xff0c;导致了企业信息管理零散…

【word技巧】word页眉,如何禁止他人修改?

我们设置了页眉内容之后&#xff0c;不想其他人修改自己的页眉内容&#xff0c;我们可以设置加密的&#xff0c;设置方法如下&#xff1a; 先将页眉设置好&#xff0c;退出页眉设置之后&#xff0c;我们选择布局功能&#xff0c;点击分隔符 – 连续 设置完之后页面分为上下两节…

基于OpenAPI、freemarker动态生成swagger文档

前言 spring项目中可以使用springfox或者springdoc&#xff0c;通过写注解的方式生成swagger文档&#xff0c;下面介绍一种不写注解&#xff0c;动态生成swagger文档的方式&#xff0c;在某些场景会适用&#xff0c;例如接口是动态生成的&#xff0c;此时swagger就不能通过注解…

Qt中QFile、QByteArray QDataStream和QTextStream区别及示例

在Qt中&#xff0c;QFile、QByteArray、QDataStream和QTextStream是常用的文件和数据处理类。 主要功能和区别 QFile&#xff1a; QFile是用于读写文本和二进制文件以及资源的I/O设备。可以单独使用QFile&#xff0c;或者更方便地与QTextStream或QDataStream一起使用。 通常在…

Cookie和Session

前言扩展&#xff1a;笔者在之前学习前端扫盲阶段&#xff0c;写过一个简单易读的&#xff1a;表白墙项目&#xff0c;具体的前端代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta ht…

mac安装+配置python3环境

一、python3下载 官网下载 https://www.python.org/ 二、python3安装 打开下载好的.pkg文件一直继续确认即可。 三、验证是否安装成功 打开终端&#xff0c;输入python3&#xff0c;如果返回python对应的版本信息&#xff0c;则安装成功。 四、python配置 如果需要输入…

基于卷积优化优化的BP神经网络(分类应用) - 附代码

基于卷积优化优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于卷积优化优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.卷积优化优化BP神经网络3.1 BP神经网络参数设置3.2 卷积优化算法应用 4.测试结果…

Qt窗体设计的布局

本文介绍Qt窗体的布局。 Qt窗体的布局分为手动布局和自动布局&#xff0c;手动布局即靠手工排布各控件的位置。而自动布局则是根据选择的布局类型自动按此类型排布各控件的位置&#xff0c;使用起来比较方便&#xff0c;本文主要介绍Qt的自动布局。 1.垂直布局 垂直布局就是…

基于WebRTC构建的程序因虚拟内存不足导致闪退问题的排查以及解决办法的探究

目录 1、WebRTC简介 2、问题现象描述 3、将Windbg附加到目标进程上分析 3.1、Windbg没有附加到主程序进程上&#xff0c;没有感知到异常或中断 3.2、Windbg感知到了中断&#xff0c;中断在DebugBreak函数调用上 3.3、32位进程用户态虚拟地址和内核态虚拟地址的划分 …

义乌再次位列第一档!2022年跨境电商综试区评估结果揭晓!

义乌跨境电商综试区捷报频传&#xff0c;在商务部公布的“2022年跨境电子商务综合试验区评估”结果中&#xff0c;中国&#xff08;义乌&#xff09;跨境电子商务综合试验区&#xff08;以下简称&#xff1a;“跨境综试区”&#xff09;评估结果为成效明显&#xff0c;综合排名…

【C++技能树】Lambda表达式

Halo&#xff0c;这里是Ppeua。平时主要更新C&#xff0c;数据结构算法&#xff0c;Linux与ROS…感兴趣就关注我bua&#xff01; 文章目录 0. Lambda表达式简介1. Lambda表达式2. Lambda表达式语法 0. Lambda表达式简介 在C98及之前,想要对sort进行自定义排序,或者对自定义类…