Java排序算法总结之(一)——插入排序(直接插入排序、折半插入排序、希尔排序)

java中折半法查找方法 在数组中用java折半法查找指定的数字,提供了2个方法,一个是递归另一个不是递归方法,好东西大家分享。。。 立即下载

排序方法可以分为两种:内部排序 和 外部排序

内部排序的方法很多,常用的大致可以分为:

  1. 插入排序(直接插入排序、折半插入排序、希尔排序)
  2. 交换排序(冒泡排序、快速排序)
  3. 选择排序(简单选择排序、堆排序)
  4. 归并排序
  5. 基数排序

评价排序算法的优劣一般从三个角度分析:

  • 空间复杂度:存储器使用量
  • 时间复杂度:最差、最好和平均时间复杂度
  • 稳定性。当序列中出现相等的数据时,经过排序后,前后顺序位置不变。

插入排序(Insertion Sort)

插入排序是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:

  1. 从第一个元素开始,该元素可以认为已经被排序
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
  5. 将新元素插入到该位置后
  6. 重复步骤2~5
插入排序有很多种实现方式:

1 直接插入排序

基本操作:将一个数据插入到已排好序的有序表中,从而得到一个新的、长度加 1 的有序表,直接插入的步长为 1,即待插入的数据为当前有序表的下一数据。

图例:

         

代码:

package com.yanshx.sort;

public class InsertSort {
	//直接插入排序
	public static int[] insertSort(int[] s){
		
		for (int i = 1; i < s.length; i++) {//i = 0一个数据可以看成一个有序表,故从i = 1开始
			int j = i;
			while (j > 0 && s[j] < s[j - 1]) {//将每一位向后移动一位,直到将s[i]插入到合适的位置上
				int temp = s[j];
				s[j] = s[j - 1];
				s[j - 1] = temp;
				j -= 1;//从后向前扫描
			}
		}
		return s;
	}
	
	}
}

效率分析:

空间:只需要一个记录的辅助空间,空间复杂度O(1)。

时间:排序的基本操作为:比较两个数据的大小和移动记录。当待排序列按正序(即我们想要的顺序)排列时,进行的比较比较次数为最小值 n - 1 次,移动 0 次;而当序列为逆序时,比较次数达到最大值 n(n-1)/2,移动 n(n-1)/2 次。若序列为随机的,则待排序序列各种排列的概率相同,可取最小值与最大值的平均,时间复杂度为O(n^2)。

稳定性:true.当两者大小相等时,不进行交换,故前后顺序不变,稳定。

如果比较操作的代价比交换操作大的话,可以采用二分查找法来减少比较操作的数目。该算法可以认为是插入排序的一个变种,称为二分查找插入排序(又叫折半插入排序法)。

2 折半插入排序法

基本概念:是直接插入排序的一种改进。因为待插入元素前的序列为有序序列,折半查找的方法来加快寻找插入点的速度。

代码:

public static int[] binInsertSort(int[] s) {
<span style="white-space:pre">		</span>for (int i = 1; i < s.length; i++) {
<span style="white-space:pre">			</span>if (s[i] < s[i - 1]) {
<span style="white-space:pre">				</span>int mid;// 记录折半后的中间值
<span style="white-space:pre">				</span>int start = 0, end = i - 1;
<span style="white-space:pre">				</span>int temp = s[i];// 寄存当前需要插入的值
<span style="white-space:pre">				</span>while (start <= end) {// 跳出时,start的位置就是要插入的位置(start = end + 1)
<span style="white-space:pre">					</span>mid = start + (end - start) / 2;
<span style="white-space:pre">					</span>if (temp < s[mid]) {// 待插入的值小于中间值,则插入点在低半区
<span style="white-space:pre">						</span>end = mid - 1;
<span style="white-space:pre">					</span>}else { // <span style="font-family: Arial, Helvetica, sans-serif;">待插入的值大于中间值,则插入点在高半区</span>
<span style="white-space:pre">						</span>start = mid + 1;
<span style="white-space:pre">					</span>}
<span style="white-space:pre">				</span>}
<span style="white-space:pre">				</span>for (int j = i; j > start; j--) {
<span style="white-space:pre">					</span>s[j] = s[j - 1];
<span style="white-space:pre">				</span>}
<span style="white-space:pre">				</span>s[start] = temp;
<span style="white-space:pre">			</span>}
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>return s;
<span style="white-space:pre">	</span>}

效率分析:
复杂度:时间与空间复杂度和直接插入排序算法一样

稳定性:true.

3 希尔排序

基本概念:希尔排序又称“缩小增量排序”,先将整个待排序序列分割成若干子序列分别进行插入排序,分割规则为设定一个步长delta,每次比较 i, i + delta, i + 2*delta...序列,进行插入排序,然后缩短步长delta(一般取当前值的一半),直到delta = 1,对全体进行一次直接插入排序。

希尔排序示例:左图摘自严蔚敏等编著的数据结构一书,右图为算法的动态展示。


代码:

package com.yanshx.sort;

public class InsertSort {
	
	//希尔排序
	public static int[] shellSort(int[] s){
		int delta = s.length;
		while (true) {
			delta = delta / 2;//步长选择
			for (int i = delta; i < s.length; i++) {
					int k = i;
					while (k > delta - 1 && s[k] < s[k - delta]) {
						int temp = s[k];
						s[k] = s[k - delta];
						s[k - delta] = temp;
						k -= delta;
					}
			}
			if (delta == 1) {//步长为1时,排序一遍后即退出
				break;
			}
		}
		
		return s;
	}
}

效率分析:

空间:O(1)

时间:步长选择是希尔排序的重要部分,不同步长下对应的最坏情况复杂度是不同的。

步长序列 最坏情况下复杂度
2^k - 1\mathcal{O}(n^{3/2})
{n/2^i}\mathcal{O}(n^2)
2^i 3^j\mathcal{O}( n\log^2 n )
稳定性:false.大步长的情况下可能会影响相等数据的相对顺序。

参考文献:

  1. 插入排序-Wikipedia
  2. 排序算法-Wikipedia
  3. [97严] 严蔚敏,吴伟民,《数据结构C语言版》,清华大学出版社,1997年4月

步长序列 最坏情况下复杂度
2^k - 1\mathcal{O}(n^{3/2})
{n/2^i}\mathcal{O}(n^2)
2^i 3^j\mathcal{O}( n\log^2 n )
MOOS-ivp实战:从零搭建水下机器人通信系统(Ubuntu 22.04版) 本文详细介绍了在Ubuntu 22.04系统上从零开始搭建MOOS-ivp水下机器人通信系统的完整实战流程。内容涵盖环境准备、核心安装、MOOSDB通信模型解析、自定义应用节点开发、以及调试监控工具链的使用,旨在帮助开发者快速掌握这一分布式机器人系统框架,构建稳定可靠的水下机器人通信与控制系统。 阅读详情

相关推荐

华为S5700三层交换机VLAN配置避坑指南:为什么你的VLAN间无法互通?

本文针对华为S5700三层交换机VLAN间无法互通的典型故障,提供深度排障指南。文章从数据转发原理入手,系统梳理了从物理链路、VLAN配置、VLANIF接口状态、路由表到ARP表、MTU及安全策略等全链路检查点,并给出了清晰的排查命令与流程,帮助网络工程师快速定位并解决VLAN间路由问题,实现稳定互通。

tt34567的博客 873

折半查找法.java

哈喽,很高兴见到大家,这次是用java语言写的折半查找法,实际上, 小白通过对比C语言里的二分法,小白发现,这两种办法的原理相同。 可以参考高中学的查找零点的办法。 import java.util.Scanner; public class 折半法查找 { public static void main(String[] args) { // TODO 自动生成的方法存根 Scanner reader=new Scanner(System.in); int n=0; System.ou

gsq521wy的博客 823

xctf攻防世界 MISC高手进阶区 low

1. 进入环境,下载附件 给出的一张bmp图片,没有其他信息 2. 问题分析 扔进binwalk中,没有发现有用信息 使用zsteg,没有有用信息 塞入StegSolve中,发现有点猫腻,如图: 有点二维码的感觉,emmm,需要像素处理,但不知道如何下手,参考网上的wp,发现是让使用lsb隐写,copy代码: from PIL import Image img = Image.open('./pic/low.bmp') img_tmp = img.copy() pix = img_tmp.load()

l8947943的博客 1万+

折半算法JAVA实现

折半算法实现方法一:循环实现 public static int biSearch(int[] arr,int num) { int low = 0; int high = arr.length-1; int middle; while(low<=high){ middle = (low+high)/2;

哟哟哟哟哟哟 1198

FFmpeg硬件加速实战:VAAPI驱动配置全攻略(含NVIDIA/Intel避坑指南)

本文详细解析了在Linux环境下配置FFmpeg使用VAAPI接口实现硬件加速的完整流程。针对NVIDIA、Intel等主流显卡,提供了从驱动安装、环境变量设置到多显卡切换的实战指南,并重点解决了闭源驱动冲突、国产系统适配等常见问题,帮助用户有效提升视频处理性能。

weixin_29306011的博客 456

ESP32驱动Xbox Series X手柄的BLE协议实现

蓝牙低功耗(BLE)是嵌入式设备无线交互的核心技术,其GATT协议架构支持自定义服务与特征值通信,广泛应用于游戏外设、工业遥控等场景。Xbox Series X手柄采用非标准私有BLE协议,需深度解析输入报告(64字节)、输出控制(振动/LED)及固件兼容性约束。该方案依托ESP32平台与NimBLE 2.1.0+协议栈,解决MTU协商、PHY配置与HCI事件同步等关键问题,实现125Hz实时输入采集与毫秒级振动反馈。适用于机器人遥操作、ROS2终端、LVGL交互界面等工程实践,是私有BLE设备逆向集成的典

weixin_42610671的博客 710

特殊回文数、杨辉三角形、查找整数、数列特征

文章目录特殊的回文数回文数特殊的数字 特殊的回文数 在这里插入代码片 回文数 在这里插入代码片 特殊的数字 在这里插入代码片

S_123789的博客 712

Cloudflare 5秒盾逆向实战:13次请求背后的Python补环境框架搭建指南

本文深入解析了如何通过Python构建浏览器环境模拟框架,以应对Cloudflare 5秒盾等现代Web防护机制。文章详细拆解了其背后复杂的13次请求链,涵盖了JavaScript执行引擎集成、DOM事件模拟、网络请求控制及Canvas指纹等环境检测的完整实现方案,为自动化数据采集和逆向工程提供了实战指南。

gold的博客 348

直接插入排序以及折半插入排序详解

一、直接插入排序 每次将一个待排序的序列插入到一个前面已排好序的子序列当中 使用到了顺序查找 图片演示 前面是有序的,逐步逐步将后面的插入到前面去 实现步骤 初始L[1]L[1]L[1] 是一个已经排好序的子序列 对于元素L(i)    (L(2)∼L(n)L(i)\;\;(L(2) \sim L(n)L(i)(L(2)∼L(n)插入到前面已经排好序的子序列当中 查找出 L(i)L(i...

Jimmy Huang's Blog 3907

VxWorks环境搭建与学习:vxworks6.8和workbench3.2

VxWorks操作系统是美国WindRiver公司于1983年设计开发的一种嵌入式实时操作系统(RTOS),是嵌入式开发环境的关键组成部分。良好的持续能力、高性能的内核以及友好的用户开发环境,在嵌入式实时操作系统领域占据一席之地。它以其良好的可靠性和卓越的实时性被广泛地应用在通信、军事、航空、航天等高精尖技术及实时性要求极高的领域中,如卫星通讯、军事演习、弹道制导、飞机导航等。

qq_41854911的博客 8469

【教程4>第2章>第18节】 GMSK调制系统的FPGA开发与matlab对比验证

GMSK(高斯最小频移键控)是一种连续相位的频移键控(CPFSK)调制方法,它在数字通信中得到了广泛应用,特别是在移动通信系统中。GMSK通过限制频率偏差的累积来减少带外辐射,并通过使用高斯滤波器对。

FPGA/MATLAB学习教程/源码/项目合作开发 998

java实现排序算法之插入排序(直接插入排序,折半插入排序,希尔排序)

插入排序:其基本思想就是每次将一个待排序的的记录,按其关键字大小插入到前面已经排好序的子序列中,直到全部记录插入完成,其主要的算法有:直接插入排序,折半插入排序,希尔排序,下面主要介绍这三个算法:

NFMSR的博客 529

Open3D 进阶(22)间接平差法拟合空间曲线

空间曲线拟合在电力线三维重建中有着广泛的应用,本文利用python使用间接平差法对三维空间曲线的拟合进行代码实现。

点云侠的博客 1058

Java实现常见排序算法(一)

在开发过程中使用得比较多的算法就是排序算法和查找算法了,今天先盘点一下常见的排序算法中的两个大类交换排序和插入排序。 交换排序 快速排序 基本思想:用选取的初始值(一般是第一个)将待排序序列分为小于初始值和大于初始值的两部分,然后重复此操作,最终到排序完成。该算法是一个不稳定的算法(如果待排序序列中存在相同的元素,经过排序后他们的相对位置不发生改变那么这个算法就是稳定的排序算法) 空间复杂度最坏为...

Alex_NINE的博客 1297

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

排序算法小结(一)——插入排序(Java实现):直接插入排序、二分(折半)插入排序、希尔排序(缩小增量排序)

排序算法小结(一)——插入排序(Java实现):直接插入排序、二分(折半)插入排序、希尔排序(缩小增量排序)

xx2014301318的博客 374

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序...

先推荐一篇关于排序算法的文章:http://www.cppblog.com/guogangj/archive/2009/11/13/100876.html 本文思路部分来源于上篇文章,但测得的结果似乎不大相同,不知是因为java的缘故还是因为我算法的缘故,欢迎拍砖。 复习排序,顺便比下各种算法的速度,榜单如下: 1、冒泡排序 2、简单选择排序 3、直接插入排序 4、折半插入排序 ...

weixin_33735077的博客 267

Java实现排序的可视化

java实现排序算法的可视化先看以下运行效果内部排序(更新时间19.11.22 22:20)一、 类图二、类列表三、源代码 先看以下运行效果 内部排序(更新时间19.11.22 22:20) ->插入类排序 –>直接插入排序(insert sort) –>折半插入排序(binary sort) –>希尔排序(shell sort) ->交换类排序 –&g...

weixin_42190209的博客 3646

数据结构-插入排序(直接插入排序,二分插入排序,希尔排序)

1,插入排序思想 插入排序是一种简单直观的排序方法,其基本思想是每次将一个待排序的记录按其关键字大小插入到前面己排好序的子序列中,直到全部记录插入完成。由插入排序的思想可以引申出三个 重要的排序算法:直接插入排序、折半插入排序和希尔排序。 2,直接插入排序 2.1,直接插入排序 根据上面的插入排序思想,不难得出一种最简单也最直观的直接插入排序算法。假设在排序过程中,待排序表L [1...n ] 在某次排序过程中的某一时刻状态如下: 有序序列L[1,2.........i-1] L(i)

理科男同学 1328

插入排序之直接插入排序,折半插入,希尔排序详解和特点

插入排序引申了三种:直接插入排序,折半插入排序,希尔排序 一、直接插入排序 直接插入排序排序方法:   1、查找出L(i)在L[1……i-1]中的位置k。   2、将L[k……i-1]所有元素全部后移一个位置。   3、将L(i)复制到L(k)。 直接插入排序排序过程: //**********直接插入排序的伪代码*************** void InsertSor...

pshdhx的博客 1万+

插入排序——直接插入排序

插入排序思想:    插入排序分有序区、无序区,最开始有序区没有元素,无序区为整个待排序区。排序时,每一趟排序将一个无序区的元素插入到有序区适当的位置,直到无序区的元素为空。    插入排序根据具体的排序算法不同,又分为直接插入排序、折半插入排序、希尔排序。直接插入排序:    直接插入排序,在寻找有序区的插入位置时,待插入元素和有序区元素依次比较。插接插入排序java实现:    /** *...

qq_42072311的博客 1115

三种插入排序代码实现 (直接插入排序 +折半插入排序 +希尔排序)

插入排序 1、直接插入排序 2、折半插入排序 3、希尔排序 1、直接插入排序 package sort; public class InsertSort {//直接插入排序 //有序区 无序区 [前:后] public static void sortA(int[] arr,int n){ int tmp;//临时值 int i,j; for(i=

四月的萤火之光的博客 2207

java 排序_Java实现常见排序算法(一)

在开发过程中使用得比较多的算法就是排序算法和查找算法了,今天先盘点一下常见的排序算法中的两个大类交换排序和插入排序。Java交换排序快速排序基本思想:用选取的初始值(一般是第一个)将待排序序列分为小于初始值和大于初始值的两部分,然后重复此操作,最终到排序完成。该算法是一个不稳定的算法(如果待排序序列中存在相同的元素,经过排序后他们的相对位置不发生改变那么这个算法就是稳定的排序算法)空间复杂度最坏为...

weixin_39669163的博客 86

linux公社 java算法_Java实现基本排序算法

本例子实现了一些常见的排序算法,注释中也有一些关于这些算法的思想的描述,这里不做多,使用Java实现基本排序算法,直接上代码。import java.awt.List;import java.util.ArrayList;import java.util.Hashtable;/*** @ClassName: Sort* @Description: //默认按照升序排序**/public class...

weixin_26891599的博客 116

选择排序算法

1.选择排序 1.算法思想 比较简单,就是先两两比较,找出未排序序列中的最小元素,存放到排序序列中的起始位置,然后找出剩余未排序序列的最小元素,存放到排序序列的末尾,依次内推,直到进行比较的只有一个数为止。时间复杂度最好最坏平均都是O(n^2),不稳定的。 2.java实现 public class Main { public static void main(String[] args) {...

weixin_43156585的博客 197
上一篇: LeetCode 235. Lowest Common Ancestor of a Binary Search Tree
下一篇: Java排序算法总结之(二)——基于交换排序(冒泡排序、快速排序)
Appletable
博客等级 码龄14年 0粉丝 36原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值