数据结构~七大排序算法(Java实现)
目录
插入排序
直接插入排序
希尔排序
选择排序
直接选择排序
堆排序
交换排序
冒泡排序
快速排序
递归实现
优化版本
归并排序
插入排序
直接插入排序
public class MySort {public static void insertSort(int[] array) {for (int i = 1; i < array.length; i++) {int j = i - 1;int tmp = array[i];for (; j >= 0; j--) {if (tmp < array[j]) {array[j + 1] = array[j];} else {break;}}array[j + 1] = tmp;}}
}
· 时间复杂度:
最好情况下O(n),即数组有序的情况
最坏情况下O(n^2),即数组逆序的情况
· 空间复杂度:O(1)
· 稳定性: 稳定的排序算法
希尔排序
public class MySort {public static void shellSort(int[] array) {for (int gap = array.length / 2; gap > 1; gap /= 2) {shell(array, gap);}shell(array, 1);}private static void shell(int[] array, int gap) {for (int i = gap; i < array.length; i++) {int j = i - gap;int tmp = array[i];for (; j >= 0; j -= gap) {if (tmp < array[j]) {array[j + gap] = array[j];} else {break;}}array[j + gap] = tmp;}}
}
· 时间复杂度:O(n^1.3)
· 空间复杂度:O(1)
· 稳定性: 不稳定的排序算法
选择排序
直接选择排序
public class MySort {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[minIndex] > array[j]) {minIndex = j;}}swap(array, minIndex, i);}}private static void swap(int[] array, int i, int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;}
}
· 时间复杂度:O(n^2)
· 空间复杂度:O(1)
· 稳定性:不稳定的排序算法
堆排序
要排升序时,建立大根堆,排降序时,建立小根堆
public class MySort {public static void heapSort(int[] array) {//1、建立大根堆 时间复杂度:O(n)createHeap(array);//2、排序 时间复杂度:O(n*logn)int end = array.length - 1;while (end > 0) {swap(array, 0, end);shiftDown(array, 0, end);end--;}}private static void createHeap(int[] array) {for (int parent = (array.length-1-1) / 2; parent >= 0; parent--) {shiftDown(array, parent, array.length);}}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;}}}private static void swap(int[] array, int i, int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;}
}
· 时间复杂度:O(n*logn) 和数据是否有序无关
· 空间复杂度:O(1)
· 稳定性:不稳定的排序算法
交换排序
冒泡排序
public class MySort {public static void bubbleSort(int[] array) {for (int i = 0; i < array.length; i++) {boolean flag = false;for (int j = 0; j < array.length - i - 1; j++) {if (array[j + 1] < array[j]) {swap(array, j + 1, j);flag = true;}}if (flag == false) {return;}}}private static void swap(int[] array, int i, int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;}
}
· 时间复杂度:O(n^2),优化后的冒泡排序时间复杂度最好可以到O(n)
· 空间复杂度:O(1)
· 稳定性:稳定的排序算法
快速排序
· 时间复杂度:
最好情况下:O(n*logn),待排序列尽量均匀的分割
最坏情况下:O(n^2),待排序列正序或逆序
· 空间复杂度:
最好情况下:O(logn)
最坏情况下:O(n)
· 稳定性:不稳定的排序算法
递归实现
public class MySort {public static void quickSort(int[] array) {quick(array, 0, array.length - 1);}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);}private static int partition(int[] array, int left, int right) {int tmp = array[left];while (left < right) {while (left < right && array[right] >= tmp) {right--;}array[left] = array[right];while (left < right && array[left] <= tmp) {left++;}array[right] = array[left];}array[left] = tmp;return left;}
}
优化版本
对于快速排序的优化,利用三数取中法选取key值,当递归到小的区间时,采用直接插入排序
public class MyQuickSort {private static final int INSERT_SIZE = 100;private static void quickSort(int[] array) {quick(array, 0, array.length - 1);}private static void quick(int[] array, int start, int end) {if (start >= end) {return;}if (end - start + 1 <= INSERT_SIZE) {insertSort(array, start, end);return;}int index = threeMid(array, start, end);swap(array, start, index);int pivot = partition(array, start, end);quick(array, start, pivot - 1);quick(array, pivot + 1, end);}/*** 针对快排的优化:key值根据三数取中法获得*/private static int threeMid(int[] array, int left, int right) {int mid = (left + right) >>> 1;if (array[left] > array[right]) {if (array[mid] > array[left]) {return left;} else if (array[mid] < array[right]) {return right;} else {return mid;}} else {if (array[mid] > array[right]) {return right;} else if (array[mid] < array[left]) {return left;} else {return mid;}}}/*** 针对快排的优化:当递归到小的区间时,快排转为插入排序*/private static void insertSort(int[] array, int start, int end) {for (int i = start + 1; i < end + 1; i++) {int j = i - 1;int tmp = array[i];for (; j >= start; j--) {if (tmp < array[j]) {array[j + 1] = array[j];} else {break;}}array[j + 1] = tmp;}}private static int partition(int[] array, int left, int right) {int tmp = array[left];while (left < right) {while (left < right && array[right] > tmp) {right--;}array[left] = array[right];while (left < right && array[left] < tmp) {left++;}array[right] = array[left];}array[left] = tmp;return left;}private static void swap(int[] array, int i, int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;}
}
归并排序
public class MySort {public static void mergeSort(int[] array) {mergeSortFunction(array, 0, array.length - 1);}private static void mergeSortFunction(int[] array, int low, int high) {if (low >= high) {return;}int mid = (low + high) >>> 1;mergeSortFunction(array, low, mid);mergeSortFunction(array, mid + 1, high);merge(array, low, high, mid);}private static void merge(int[] array, int low, int high, int mid) {int[] tmp = new int[high - low + 1];int k = 0;int start1 = low;int end1 = mid;int start2 = mid + 1;int end2 = high;while (start1 <= end1 && start2 <= end2) {if (array[start1] < array[start2]) {tmp[k++] = array[start1++];} else {tmp[k++] = array[start2++];}}while (start1 <= end1) {tmp[k++] = array[start1++];}while (start2 <= end2) {tmp[k++] = array[start2++];}for (int i = 0; i < k; i++) {array[i + low] = tmp[i];}}
· 时间复杂度:O(n*logn),不论有序或无序都是O(n*logn)
· 空间复杂度:O(n)
· 稳定性: 稳定的排序算法
相关文章:
数据结构~七大排序算法(Java实现)
目录 插入排序 直接插入排序 希尔排序 选择排序 直接选择排序 堆排序 交换排序 冒泡排序 快速排序 递归实现 优化版本 归并排序 插入排序 直接插入排序 public class MySort {public static void insertSort(int[] array) {for (int i 1; i < array.length;…...
python练习
项目场景一: 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 问题描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶…...
RPC-thrift实践
参考:https://www.cnblogs.com/52fhy/p/11146047.html 参考:https://juejin.cn/post/7138032523648598030 实践 安装thrift brew install thriftthrift -version 编写thrift文件 新建文件夹thrift新建文件 结构体文件 Struct.thrift 服务文件 Service.…...
Maven:工程的拆分与聚合
Maven 拆分与聚合创建父工程创建子模块pom.xml配置示例拆分与聚合 在 Maven 中, 拆分是将一个完整的项目分成一个个独立的小模块,聚合是将各个模块进一步组合,形成一个完整的项目。接下来简单示例拆分与聚合的过程。 创建父工程 父工程,一个pom工程,目录结构简单,只需有…...
使用uniapp创建小程序和H5界面
uniapp的介绍可以看官网,接下来我们使用uniapp创建小程序和H5界面,其他小程序也是可以的,只演示创建这2个,其实都是一套代码,只是生成的方式不一样而已。 uni-app官网 1.打开HBuilder X 选择如图所示,下…...
密度峰值聚类算法(DPC)
密度峰值聚类算法目录DPC算法1.1 DPC算法的两个假设1.2 DPC算法的两个重要概念1.3 DPC算法的执行步骤1.4 DPC算法的优缺点matlab代码密度计算函数计算delta寻找聚类中心点聚类算法目录 DPC算法 1.1 DPC算法的两个假设 1)类簇中心被类簇中其他密度较低的数据点包围…...
RabbitMQ相关问题
文章目录避免重复消费(保证消息幂等性)消息积压上线更多的消费者,进行正常消费惰性队列消息缓存延时队列RabbitMQ如何保证消息的有序性?RabbitMQ消息的可靠性、延时队列如何实现数据库与缓存数据一致?开启消费者多线程消费避免重复消费(保证消…...
操作系统 三(存储管理)
一、 存储系统的“金字塔”层次结构设计原理:cpu自身运算速度很快。内存、外存的访问速度受到限制各层次存储器的特点:1)主存储器(主存/内存/可执行存储器)保存进程运行时的程序和数据,内存的访问速度远低于…...
day34 贪心算法 | 860、柠檬水找零 406、根据身高重建队列 452、用最少数量的箭引爆气球
题目 860、柠檬水找零 在柠檬水摊上,每一杯柠檬水的售价为 5 美元。 顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。 每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个…...
使用canvas给上传的整张图片添加平铺的水印
写在开头 哈喽,各位倔友们又见面了,本章我们继续来分享一个实用小技巧,给图片加水印功能,水印功能的目的是为了保护网站或作者版权,防止内容被别人利用或白嫖。 但是网络中,是没有绝对安全的,…...
[安装之4] 联想ThinkPad 加装固态硬盘教程
方案:保留原有的机械硬盘,再加装一个固态硬盘作为系统盘。由于X250没有光驱,这样就无法使用第二个2.5寸的硬盘。还好,X250留有一个M.2接口,这样,就可以使用NGFF M.2接口的固态硬盘。不过,这种接…...
Java数据类型、基本与引用数据类型区别、装箱与拆箱、a=a+b与a+=b区别
文章目录1.Java有哪些数据类型2.Java中引用数据类型有哪些,它们与基本数据类型有什么区别?3.Java中的自动装箱与拆箱4.为什么要有包装类型?5.aab与ab有什么区别吗?1.Java有哪些数据类型 8种基本数据类型: 6种数字类型(4个整数型…...
GoLang设置gofmt和goimports自动格式化
目录 设置gofmt gofmt介绍 配置gofmt 设置goimports goimports介绍 配置goimports 设置gofmt gofmt介绍 Go语言的开发团队制定了统一的官方代码风格,并且推出了 gofmt 工具(gofmt 或 go fmt)来帮助开发者格式化他们的代码到统一的风格…...
【k8s】如何搭建搭建k8s服务器集群(Kubernetes)
搭建k8s服务器集群 服务器搭建环境随手记 文章目录搭建k8s服务器集群前言:一、前期准备(所有节点)1.1所有节点,关闭防火墙规则,关闭selinux,关闭swap交换,打通所有服务器网络,进行p…...
DIDL4_前向传播与反向传播(模型参数的更新)
前向传播与反向传播前向传播与反向传播的作用前向传播及公式前向传播范例反向传播及公式反向传播范例小结前向传播计算图前向传播与反向传播的作用 在训练神经网络时,前向传播和反向传播相互依赖。 对于前向传播,我们沿着依赖的方向遍历计算图并计算其路…...
链表学习之链表划分
链表解题技巧 额外的数据结构(哈希表);快慢指针;虚拟头节点; 链表划分 将单向链表值划分为左边小、中间相等、右边大的形式。中间值为pivot划分值。 要求:调整之后节点的相对次序不变,时间复…...
(考研湖科大教书匠计算机网络)第五章传输层-第一、二节:传输层概述及端口号、复用分用等概念
获取pdf:密码7281专栏目录首页:【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一:传输层概述(1)概述(2)从计算机网络体系结构角度看传输层(3)传输层意义二&am…...
C#:Krypton控件使用方法详解(第七讲) ——kryptonHeader
今天介绍的Krypton控件中的kryptonHeader,下面开始介绍这个控件的属性:控件的样子如上图所示,从上面控件外观来看,这个控件有三部分组成。第一部分是前面的图片,第二部分是kryptonHeader1文本,第三部分是控…...
5年软件测试工程师分享的自动化测试经验,一定要看
今天给大家分享一个华为的软件测试工程师分享的关于自动化测试的经验及干货。真的后悔太晚找他要了, 纯干货。一定要看完! 1.什么是自动化测试? 用程序测试程序,用代码取代思考,用脚本运行取代手工测试。自动化测试涵…...
什么是猜疑心理?小猫测试网科普小作文
什么是猜疑心理?猜疑心理是说一个人心中想法偏离了客观事实,牵强附会,往往是指不好的一面,对别人的一言一行都充满了不良的解读,认为这些对自己都有针对性,目的性,对自己都是不利的。猜疑心理重…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...
React核心概念:State是什么?如何用useState管理组件自己的数据?
系列回顾: 在上一篇《React入门第一步》中,我们已经成功创建并运行了第一个React项目。我们学会了用Vite初始化项目,并修改了App.jsx组件,让页面显示出我们想要的文字。但是,那个页面是“死”的,它只是静态…...
如何把工业通信协议转换成http websocket
1.现状 工业通信协议多数工作在边缘设备上,比如:PLC、IOT盒子等。上层业务系统需要根据不同的工业协议做对应开发,当设备上用的是modbus从站时,采集设备数据需要开发modbus主站;当设备上用的是西门子PN协议时…...
计算机系统结构复习-名词解释2
1.定向:在某条指令产生计算结果之前,其他指令并不真正立即需要该计算结果,如果能够将该计算结果从其产生的地方直接送到其他指令中需要它的地方,那么就可以避免停顿。 2.多级存储层次:由若干个采用不同实现技术的存储…...
