数据结构与算法-插入希尔归并

news2024/11/19 16:40:43

    一:排序引入

     我们通常从哪几个方面来分析一个排序算法?

        1.时间效率:决定了算法运行多久,O(1)

        2.空间复杂度:

        3.比较次数&交换次数:排序肯定会牵涉到两个操作,一个比较是肯定的。交换。

        4.稳定性:这是什么? 1 9 3 5 3

                第一种:1 3 3 5 9

                第二种:1 3 3 5 9  哪一种是稳定的?相同的两个数排完序后,相对位置不变。

        稳定排序有什么意义?应用在哪里呢?

                1.电商里面订单排序:首先会按金额从小到大排,金额相同的按下单时间。我从订单中心过来的时候已经按照时间排好序了。我选择排序算法:如果我选择不稳定的排序算法 那我还要比较两次的,如果我选择稳定的排序算法 那我就只要比较一个字段。

        二 核心思想:

        假设有个这样的问题:打扑克。分成两部分:一部分是你手里的牌(已经排好序),一部分是要拿的牌(无序)。

        把一个无序的数列一个个插入到有序数列中。 一个有序的数组,我们往里面添加一个新的数据后,如何继续保持数据有序呢?我们只要遍历数组,找到数据应该插入的位置将其插入即可。

        三: 具体步骤

        1.将数组分成已排序段和未排序段。初始化时已排序端只有一个元素

        2.到未排序段取元素插入到已排序段,并保证插入后仍然有序

        3.重复执行上述操作,直到未排序段元素全部加完。

        四:举例:

        看以下这个例子:对7 8 9 0 4 3进行插入排序

        7 8 9 0 4 3

        7 8 9 0 4 3

        7 8 9 0 4 3

        0 7 8 9 4 3

        0 4 7 8 9 3

        0 3 4 7 8 9

        从以上操作中我们看到插入排序会经历一个元素的比较以及元素的移动。当我们从待排序列中取一个数插入到已排序区间时,需要拿它与已排序区间的数依次进行比较,直到找到合适的位置,然后还要将插入点之后的元素进行往后移动。

        五:插入排序代码实现、

package sort;

/**
 * 插入排序
 */
public class InsertionSort {
	/**
	 * 
	 1.将数组分成已排序段和未排序段。初始化时已排序端只有一个元素 
	 2.到未排序段取元素插入到已排序段,并保证插入后仍然有序
	 3.重复执行上述操作,直到未排序段元素全部加完。
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		int a[] = { 9, 8, 7, 0, 1, 3, 2 };
		int n = a.length;
		//这里面会有几层循环 2
		//时间复杂度:n^2
		//最好的情况:什么情况下:O(n); O(1)
		//for(){		//分段
		for(int i = 1 ; i < n;i++){		//为什么i要从1开始? 第一个不用排序,我们就把数组从i分开,0~I的认为已经排好序
			int data = a[i];
			int j = i -1;
			for(;j>=0;j--){//从尾到头 1+2+3+4+5+...+n=>
				if(a[j] > data){
					a[j+1] = a[j];		// 数据往后移动
				}else{	//因为前面已经是排好序的 那么找到一个比他小的就不用找了,因为前面的肯定更小
					break; //O(1)		如果这个break执行的越多 那么我是不是效率就越高?
				}
			}	
			a[j+1] = data;
			System.out.print("第" +i +"次的排序结果为:");
			for(j = 0 ; j < n;j++){
				System.out.print(a[j]+" ");
			}
			System.out.println();
		}
		
	}

}

        六:优化 (希尔排序==>插入排序改进版)

        希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

        先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量  =1(  <  …<d2<d1),即所有记录放在同一组中进行直接插入排序为止。

来看一个具体的过程: 按照一个增量分段:add=n/2 n=10 =>5,2,1 7 8 9 0 4 3 1 2 5 10 我们取的这个增量分别就是5 2 1 7 8 9 0 4 3 1 2 5 10:分出来的数组元素都是一样的 完成一次排序: 3 1 2 0 4 7 8 9 5 3 2 4 8 5:取增量为2的分为一组了 最后一次我们就取增量为1的分组: 就是一个完整的序列,但是时间复杂度还是O(n^2)

        七:归并排序 (核心思想:递归+分治)

        主要分析时间复杂度:nlogn

        

package sort;

import java.util.Arrays;

public class MegrSort {

	public static void main(String[] args) {

		int data[] = { 9, 5, 6, 8, 0, 3, 7, 1 };
		//拆分
		megerSort(data, 0, data.length - 1);
		System.out.println(Arrays.toString(data));
		//JDK里面的排序源码

	}

	public static void megerSort(int data[], int left, int right) { // 数组的两端
		if (left < right) { // 相等了就表示只有一个数了 不用再拆了
			int mid = (left + right) / 2;
			//拆分从最左边到中间
			megerSort(data, left, mid);
			//拆分右边从中间+1到最右边
			megerSort(data, mid + 1, right);
			// 分完了 接下来就要进行合并,也就是我们递归里面归的过程
			meger(data, left, mid, right);
		}
	}

	public static void meger(int data[], int left, int mid, int right) {
		int temp[] = new int[data.length];		//借助一个临时数组用来保存合并的数据
		
		int point1 = left;		//表示的是左边的第一个数的位置
		int point2 = mid + 1;	//表示的是右边的第一个数的位置
		
		int loc = left;		//表示的是我们当前已经到了哪个位置了
		while(point1 <= mid && point2 <= right){
			if(data[point1] < data[point2]){
				temp[loc] = data[point1];
				point1 ++ ;
				loc ++ ;
			}else{
				temp[loc] = data[point2];
				point2 ++;
				loc ++ ;
			}
		}
		//接下来要干嘛呢?合并排序完成 了吗?
		while(point1 <= mid){
			temp[loc ++] = data[point1 ++];
		}
		while(point2 <= right){
			temp[loc ++] = data[point2 ++];
		}
		for(int i = left ; i <= right ; i++){
			data[i] = temp[i];
		}
	}
}

        这段代码实现了归并排序算法。归并排序是一种分治算法,它将一个数组分成两个子数组,分别对其进行递归排序,然后将两个有序的子数组合并成一个有序的数组。 代码中的megerSort方法是归并排序的主要方法,它接受一个数组和两个索引值作为参数,表示需要排序的数组和需要排序的范围。如果左索引小于右索引,则将数组分为两半,分别对左半部分和右半部分进行递归调用megerSort方法。递归调用结束后,再调用meger方法将两个有序的子数组合并成一个有序的数组。 meger方法创建了一个临时数组temp,用来保存合并的结果。变量point1point2分别表示左半部分和右半部分的起始位置。变量loc表示当前合并的位置。在循环中,比较左右两个子数组的元素大小,将较小的放入临时数组中,并将对应的指针向后移动。循环结束后,将剩余的元素依次放入临时数组中。最后,将临时数组的元素复制回原数组的对应位置。 整个归并排序的过程是递归的,每一次递归都会将数组分为两半,直到只有一个元素为止。然后通过合并两个有序的子数组来实现整个数组的排序。最后,通过递归调用megerSort方法将整个数组排序完成。

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

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

相关文章

mac常见问题(五) Mac 无法开机

在mac的使用过程中难免会碰到这样或者那样的问题&#xff0c;本期为您带来Mac 无法开机怎么进行操作。 1、按下 Mac 上的电源按钮。每台 Mac 电脑都有一个电源按钮&#xff0c;通常标有电源符号 。然后检查有没有通电迹象&#xff0c;例如&#xff1a; 发声&#xff0c;例如由风…

springmvc5.x-mvc实现原理及源码实现

上文&#xff1a;spring5.x-声明式事务原理及源码实现 系列文章&#xff1a; spring5.x-声明式事务原理及源码实现 spring5.x-AOP实现原理及源码分析 spring5.x-监听器原理及源码实现 spring5.x-解决循环依赖分析 spring5.x-IOC模块源码学习 spring5.x介绍及搭配spring源码阅读…

Xcode 清空最近打开的项目

打开Xcode任意项目 File -> Open Recent -> Clear Menu

桌面应用小程序,一种创新的跨端开发方案

Qt Group在提及2023年有桌面端应用程序开发热门趋势时&#xff0c;曾经提及三点&#xff1a; 关注用户体验&#xff1a;无论您是为桌面端、移动端&#xff0c;还是为两者一起开发应用程序&#xff0c;有一点是可以确定的&#xff1a;随着市场竞争日益激烈&#xff0c;对产品的期…

怎么批量在图片名后加相同的文字

怎么批量在图片名后加相同的文字&#xff1f;有个小伙伴通过私信想我咨询一个问题&#xff0c;它从事的是摄影类的工作&#xff0c;每天会在电脑上存储非常多的图片&#xff0c;时间一久电脑上保存的图片非常的多&#xff0c;这让图片的管理和查找变得比较麻烦&#xff0c;有时…

从智能手机到智能机器人:小米品牌的高端化之路

原创 | 文 BFT机器人 前言 在前阵子落幕的2023世界机器人大会“合作之夜”上&#xff0c;北京经济技术开发区管委会完成了与世界机器人合作组织、小米机器人等16个重点项目签约&#xff0c;推动机器人创新链和产业链融合&#xff0c;其中小米的投资额达到20亿&#xff01; 据了…

E5061B/是德科技keysight E5061B网络分析仪

181/2461/8938产品概述 是德科技E5061B(安捷伦)网络分析仪在从5 Hz到3 GHz的宽频率范围内提供通用的高性能网络分析。E5061B提供ENA系列常见的出色RF性能&#xff0c;还提供全面的LF(低频)网络测量能力&#xff1b;包括内置1 Mohm输入的增益相位测试端口。E5061B从低频到高频的…

通过cpolar内网穿透,在家实现便捷的SSH远程连接公司内网服务器教程

文章目录 1. Linux CentOS安装cpolar2. 创建TCP隧道3. 随机地址公网远程连接4. 固定TCP地址5. 使用固定公网TCP地址SSH远程 本次教程我们来实现如何在外公网环境下&#xff0c;SSH远程连接家里/公司的Linux CentOS服务器&#xff0c;无需公网IP&#xff0c;也不需要设置路由器。…

VLAN间路由:单臂路由与三层交换

文章目录 一、定义二、实现方式单臂路由三层交换 三、单臂路由与三层路由优缺点对比四、常用命令 首先可以看下思维导图&#xff0c;以便更好的理解接下来的内容。 一、定义 VLAN间路由是一种网络配置方法&#xff0c;旨在实现不同虚拟局域网&#xff08;VLAN&#xff09;之…

pdf文件过大如何缩小上传?pdf压缩跟我学

在我们日常工作和生活中&#xff0c;经常会遇到PDF文件过大的问题&#xff0c;给文件传输和存储带来了很大的不便。那么&#xff0c;如何缩小PDF文件大小以便上传呢&#xff1f;下面就给大家分享几个压缩方法&#xff0c;一起来了解下PDF文件压缩方法吧~ 方法一&#xff1a;嗨格…

数据结构——七大排序[源码+动图+性能测试]

本章代码gitee仓库&#xff1a;排序 文章目录 &#x1f383;0. 思维导图&#x1f9e8;1. 插入排序✨1.1 直接插入排序✨1.2 希尔排序 &#x1f38a;2. 选择排序&#x1f38b;2.1 直接选择排序&#x1f38b;2.2 堆排序 &#x1f38f;3. 交换排序&#x1f390;3.1 冒泡排序&#…

TS编译选项

自动监控编译 tsc xxx.ts -w 在一个文件夹下&#xff0c;创建 tsconfig.json 文件&#xff0c;在用命令 tsc 就可以自动编译当前文件夹下的ts文件 tsconfig.json文件配置如下&#xff1a; {/*tsconfig.json 是ts编译器的配置文件&#xff0c;ts编译器可以根据它的信息来对代…

mysql 的增删改查以及模糊查询、字符集语句的使用

一、mysql启动与登陆(windows下的mysql操作) 1.启动mysql服务 net start mysql81 2.登陆mysql mysql -uroot -p 3.查看所有数据库 show databases; 二、模糊查询&#xff08;like&#xff09; 1. _代表查询单个 2.%代表查询多个 3.查找所有含有schema的数据库&#xff1b;…

钡铼技术BL122DN实现DNP3.0转Profinet协议的双向数据传输

引言 随着工业自动化技术的不断发展&#xff0c;各种通信协议和标准层出不穷。BL122DN DNP3.0转Profinet协议网关作为一种高效的解决方案&#xff0c;在工业自动化领域发挥着重要作用。本文将详细介绍BL122DN DNP3.0转Profinet协议网关的特点、功能和优势&#xff0c;以及在实…

使用ppt和texlive生成eps图片(高清、可插入latex论文)

一、说明 写论文经常需要生成高清的图片插入到论文中&#xff0c;本文以ppt画图生成高质量的eps图片的实现来介绍具体操作方法。关于为什么要生成eps图片&#xff0c;一个是期刊要求&#xff08;也有不要求的&#xff09;&#xff0c;另一个是显示图像的质量高。 转化获得eps…

SpringCloud(36):Nacos服务发现基础应用

1 服务发现数据模型 Nacos在经过阿里内部多年生产经验后提炼出的数据模型,则是一种服务-集群-实例的三层模型,这样基本可以满足服务在所有场景下的数据存储和管理。 命名空间(Namespace) 用于进行租户粒度的配置隔离,命名空间不仅适用于nacos的配置管理,同样适用于服务发…

【Vue】实现当前页面刷新的四种方法

目录 前言方法一&#xff1a;location.reload方法二&#xff1a;$router.go(0)方法三&#xff1a;provide、inject和$nextTick方法四&#xff1a;创建空白页 前言 这两周在写一个后台管理&#xff0c;每次调用接口实现增删改查的过程中&#xff0c;都需要刷新当前页面或者刷新…

web pdf 拖拽签章

web pdf 拖拽签章 主要通过火狐的pdfjs 来实现 1. 下载js 并编译 地址 https://mozilla.github.io/pdf.js/ 按照官网当下下载并编译就得到了js 2.其实也没有什么好讲的&#xff0c;都是用的js中的方法&#xff0c;官网中都有 按照步骤就能生成一个document元素&#xff0c;然…

低压配电室电力安全解决方案

低压电气安全监控运维系统是力安科技基于物联网核心技术自主开发的高可靠性安全监测系统。其工作原理是利用物联网、云计算、大数据、数字传感技术及RFID无线射频识别技术来获取低压配电回路电压、电流、温度、有功、无功、功率因数等全电量的采集及配电线路的漏电、温度的实时…

Java智慧工地大数据中心源码

智慧工地技术架构&#xff1a;微服务JavaSpring Cloud VueUniApp MySql 智慧工地形成安全、质量、进度、人员、机械、绿色施工六大针对性解决方案。 安全管理 围绕重大危险源提供管控&#xff0c;可视化跟踪消防、安防、基坑、高支模、临边防护、卸料平台等设施设备的安全状态…