排序算法:插入排序和希尔排序

一、插入排序

1.基本原理

插入排序(英语:Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

2.动态图

在这里插入图片描述
在这里插入图片描述

3.代码

①:交换方式

public class ThreadNew{public static void main(String[] args) {int[] arr = new int[] {6,5,3 ,1,8,7,2,4};Sort(arr);}public static void Sort(int[] arr) {for (int i = 1; i < arr.length; i++) {//将当前数据插入到已经有序的数字当中(这里需要倒着往前找)for ( int j = i-1; j >= 0; j--) {//前后位置进行交换if (arr[j] > arr[j+1]) {int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}else {break;}}System.out.println(Arrays.toString(arr));}}
}

②:移位方式

public class InsertSort {public static void main(String[] args) {int[] arr = {-1,100,4,23,2,45,67,89,-3,56};System.out.print("排序前:");System.out.println(Arrays.toString(arr));insertSort(arr);}//直接插入排序(移位方式)public static void insertSort(int[] arr){for(int i=1;i<arr.length;i++){int insertVal = arr[i];int insertIndex = i;while (insertIndex>0 && insertVal<arr[insertIndex-1]){arr[insertIndex]=arr[insertIndex-1];insertIndex--;}arr[insertIndex] = insertVal;//输出每趟的结果System.out.print("第" + i + "轮:");System.out.println(Arrays.toString(arr));}//排序完成后输出最终的结果System.out.println("==================================================");System.out.println(Arrays.toString(arr));}
}

二、希尔排序

1.简单插入排序存在的问题

数组arr = {2,3,4,5,6,1}这时要插入的数据1(最小),过程是这样的:
{2,3,4,5,6,6}
{2,3,4,5,5,6}
{2,3,4,4,5,6}
{2,3,3,4,5,6}
{2,2,3,4,5,6}
{1,2,3,4,5,6}
结论:当需要插入得数是较小的数时,后移的次数明显增多,对效率有影响

2.希尔排序介绍

希尔排序也是一种插入排序。它是简单插入排序进过改进之后的一个更高效的版本,也成为了缩小增量排序

3.希尔排序的基本思想

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量主键递减,每组包含的关键词也来越多,当增量减至1时,整个文件恰被分成一组,算法终止。如下图:
在这里插入图片描述
在这里插入图片描述

4.交换式 算法实现

public class ShellSort {public static void main(String[] args) {int arr[] = new int[]{8,9,1,7,2,3,5,4,6,0};shellSort(arr);}// 使用逐步推导的方式来编写希尔排序public static void shellSort(int[] arr){// 第一轮:是将10个数据分成了5组,这里的 i 值得是我们的步长,// 既 我们的 i 指向一组元素当中的 第二个 :注意是第二个for (int i = 5 ;i < arr.length;i++){// 定义 指针 j : 指向数组当中的每一个元素  默认 j 指向的是该组当中的第一个元素// j -= 5 :这里的 5 值得是步长for(int j = i-5; j>=0; j -= 5){// 如果当前元素大于加上步长之后的元素,则交换if(arr[j] > arr[j+5]){int temp = arr[j];arr[j] = arr[j+5];arr[j+5] = temp;}}}// 第二轮:是将10个数据分成了2组,这里的 i 值得是我们的步长,// 既 我们的 i 指向一组元素当中的 第二个 :注意是第二个for (int i = 2 ;i < arr.length;i++){// 定义 指针 j : 指向数组当中的每一个元素  默认 j 指向的是该组当中的第一个元素// j -= 2 :这里的 2 值得是步长for(int j = i-2; j>=0; j -= 2){// 如果当前元素大于加上步长之后的元素,则交换if(arr[j] > arr[j+2]){int temp = arr[j];arr[j] = arr[j+2];arr[j+2] = temp;}}}// 第三轮:是将10个数据分成了1组,这里的 i 值得是我们的步长,// 既 我们的 i 指向一组元素当中的 第二个 :注意是第二个for (int i = 1 ;i < arr.length;i++){// 定义 指针 j : 指向数组当中的每一个元素  默认 j 指向的是该组当中的第一个元素// j -= 2 :这里的 2 值得是步长for(int j = i-1; j>=0; j -= 1){// 如果当前元素大于加上步长之后的元素,则交换if(arr[j] > arr[j+1]){int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}System.out.println(Arrays.toString(arr));}//最后的整合代码for(int gap = arr.length /2;gap > 0;gap /= 2){for (int i = gap ;i < arr.length;i++){// 定义 指针 j : 指向数组当中的每一个元素  默认 j 指向的是该组当中的第一个元素// j -= gap :这里的 gap 值得是步长for(int j = i-gap; j>=0; j -= gap){// 如果当前元素大于加上步长之后的元素,则交换if(arr[j] > arr[j+gap]){int temp = arr[j];arr[j] = arr[j+gap];arr[j+gap] = temp;}}}}}

完成以后我们来进行一下测试,让他和我们的直接插入排序进行对比。

public static void main(String[] args) {int[] arr = new int[80000];for(int i = 0;i< 80000;i++){arr[i] = (int) (Math.random()*80000);}long startTime=System.nanoTime();   //获取开始时间shellSort(arr);long endTime=System.nanoTime(); //获取结束时间System.out.println("希尔排序运行时间: "+(endTime-startTime)+"ns");long startTime1=System.nanoTime();   //获取开始时间insertsort(arr);long endTime1=System.nanoTime(); //获取结束时间System.out.println("直接插入运行时间: "+(endTime1-startTime1)+"ns");
}

在这里插入图片描述
这个时间差距好像不是我们想要看到的结果。
耗时的原因:交换所产生的的耗时
在这里插入图片描述

5.移位式 算法实现

// 这个算法需要仔细去推敲
public static void shellSort2(int[] arr){for(int gap = arr.length /2;gap > 0;gap /= 2){for (int i = gap ;i < arr.length;i++){int j = i;int temp = arr[j];if(arr[j] <arr[j-gap]){while (j - gap >=0 && temp <arr[j-gap]){//移动arr[j] = arr[j-gap];j -= gap;}arr[j] = temp;}}}
}

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

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

相关文章

排序算法:冒泡排序和简单选择排序

一、冒泡排序 1.冒泡排序的基本原理 对存放原始数组的数据&#xff0c;按照从前往后的方向进行多次扫描&#xff0c;每次扫描都称为一趟。当发现相邻两个数据的大小次序不符合时&#xff0c;即将这两个数据进行互换&#xff0c;如果从小大小排序&#xff0c;这时较小的数据就…

python将conda环境打入docker环境中

1.假设你本地已经安装好了conda相关的 ubuntu安装python以及conda-CSDN博客 并且已经创建启动过相关的环境&#xff0c;并且install了相关的包。 我本地的conda环境叫做,gptsovits_conda3 2.下载conda打包工具 conda install conda-pack pip install conda-pack 3.打包 con…

蓝桥杯day6队列-3.3

目录 1.约瑟夫环 1.注意&#xff01;q.push(q.front()); 2.机器翻译 3.小桥的神秘礼盒 4.餐厅排队 1.约瑟夫环 今天学习了队列的STL写法&#xff0c;来试试这个题。 #include<bits/stdc.h> using namespace std;int main() {int n,m;cin>>n>>m;queue&l…

基于uniapp cli项目开发的老项目,运行报错path.replace is not a function

项目&#xff1a;基于uniapp cli的微信小程序老项目 问题&#xff1a;git拉取代码&#xff0c;npm安装包时就报错&#xff1b; cnpm能安装成功包&#xff0c;运行报错 三种方法尝试解决&#xff1a; 更改代码&#xff0c;typeof pathstring的话&#xff0c;才走path.replace…

稀疏数组实现

博文主要是自己学习的笔记&#xff0c;供自己以后复习使用&#xff0c; 参考的主要教程是B站的 尚硅谷数据结构和算法 稀疏数组(sparse array) 实际需求&#xff1a;五子棋程序中的存盘退出和续上盘的功能 问题分析&#xff1a; 如果直接用二维数组&#xff0c;很多值是默认…

定时执行专家V7.1 多国语言版本日文版发布 - タスク自動実行ツールV7.1 日本語版リリース

◆ 软件介绍  ソフトの紹介 《定时执行专家》是一款制作精良、功能强大、毫秒精度、专业级的定时任务执行软件。软件具有 25 种【任务类型】、12 种【触发器】触发方式&#xff0c;并且全面支持界面化【Cron表达式】设置。软件采用多线程并发方式检测任务触发和任务执行&…

前端性能优化 | CDN缓存

前言 CDN&#xff08;Content Delivery Network&#xff09;是一种分布式的网络架构&#xff0c;通过在全球各地部署节点服务器来快速传输和分发网络内容。CDN的主要目标是提供快速、可靠的内容传输&#xff0c;以提升用户体验。 本文主要从以下方面讲解CDN 什么是CDNCDN的作…

外贸常用的出口认证 | 全球外贸数据服务平台 | 箱讯科技

出口认证是一种贸易信任背书&#xff0c;对许多外贸从业者而言,产品的出口认证和当前的国际贸易环境一样复杂多变&#xff0c;不同的目标市场、不同的产品类别,所需要的认证及标准也不同。 国际认证 01 IECEE-CB IECEE-CB体系的中文含义是“关于电工产品测试证书的相互认可体…

数据库-第六/七章 关系数据理论和数据库设计【期末复习|考研复习】

前言 总结整理不易&#xff0c;希望大家点赞收藏。 给大家整理了一下数据库系统概论中的重点概念&#xff0c;以供大家期末复习和考研复习的时候使用。 参考资料是王珊老师和萨师煊老师的数据库系统概论(第五版)。 文章目录 前言第六章 关系数据理论6.1 规范化6.2 范式6.3 规范…

C#,入门教程(26)——数据的基本概念与使用方法

上一篇&#xff1a; C#&#xff0c;入门教程(25)——注释&#xff08;Comments&#xff09;你会吗&#xff1f;看多图演示&#xff0c;学真正注释。https://blog.csdn.net/beijinghorn/article/details/124681888 本文所述的知识基本上适用于C/C&#xff0c;java等其他语言。 …

LVS集群 ----------------(直接路由 )DR模式部署

一、LVS集群的三种工作模式 lvs-nat&#xff1a;修改请求报文的目标IP,多目标IP的DNAT lvs-dr&#xff1a;操纵封装新的MAC地址&#xff08;直接路由&#xff09; lvs-tun&#xff1a;隧道模式 lvs-dr 是 LVS集群的 默认工作模式 NAT通过网络地址转换实现的虚拟服务器&…

在分布式环境中使用状态机支持数据的一致性

简介 在本文中&#xff0c;我们将介绍如何在分布式系统中使用transaction以及分布式系统中transaction的局限性。然后我们通过一个具体的例子&#xff0c;介绍了一种通过设计状态机来避免使用transaction的方法。 什么是数据库transaction Transaction是关系型数据普遍支持的…

java SSM流浪宠物救助与领养myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM流浪宠物救助与领养管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系…

Fragment

1.网格视图(随便插进来一条) 2.Fragment

谷歌开源的LLM大模型 Gemma 简介

相关链接&#xff1a; Hugging face模型下载地址&#xff1a;https://huggingface.co/google/gemma-7bGithub地址&#xff1a;https://github.com/google/gemma_pytorch论文地址&#xff1a;https://storage.googleapis.com/deepmind-media/gemma/gemma-report.pdf官方博客&…

Linux——文件标识符

目录 一、文件基础 二、常见的C语言文件接口 三、系统文件接口 四、理解语言与系统文件操作的关系 五、如何理解一切皆文件 六、文件标识符再理解 一、文件基础 一个空文件&#xff0c;也会占用磁盘空间&#xff0c;这是因为文件不仅仅有存放在里面的内容&#xff0c;还…

Chapter20-Ideal gases-CIE课本要点摘录、总结(编辑中)

20.1 Particles of a gas Brownian motion Fast modules 速率的数值大概了解下&#xff1a; average speed of the molecules:400m/s speed of sound:approximately 330m/s at STP&#xff08;standard temperature and pressure&#xff09; Standard Temperature and Pres…

ROS 2基础概念#5:执行器(Executor)| ROS 2学习笔记

在ROS 2中&#xff0c;Executor是一个核心概念&#xff0c;负责管理节点&#xff08;Node&#xff09;中的回调函数&#xff0c;如订阅消息的回调、服务请求的回调、定时器回调等。Executor决定了何时以及如何执行这些回调&#xff0c;从而在ROS 2系统中实现异步编程。 ROS 2 …

七彩虹八渐变 外贸建站公司wordpress模板

进出口水果wordpress外贸模板 漂亮水果wordpress外贸模板&#xff0c;做水果进出品生意的外贸公司自建站官网模板。 https://www.jianzhanpress.com/?p3516 玩具wordpress外贸模板 简洁玩具wordpress外贸模板&#xff0c;适合做跨境电商外贸公司使用的wordpres外贸s网站主题…

FPGA 按键控制串口发送

按键消抖 消抖时间一般为10ms&#xff0c;我使用的板子是ACX720&#xff0c;晶振为50MHZ&#xff0c;20ns为一周期。 状态机 模块设计 设计文件 timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2023/01/11 12:18:36 // Design Name: // Module Name…