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

    一:排序引入

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

        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.mzph.cn/news/67436.shtml

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

相关文章

《存储IO路径》专题:块设备层多队列blk-mq架构

我们想象一下&#xff0c;你是一个餐厅的厨师&#xff0c;你要准备很多不同的菜肴&#xff0c;而每种菜肴需要不同的食材和烹饪时间。如果每道菜都按照需要的顺序来准备&#xff0c;那么你的工作效率一定会非常低。为了提高效率&#xff0c;你会怎么做呢&#xff1f; 在linux架…

uni-app 之 v-on:click点击事件

uni-app 之 v-on:click点击事件 image.png <template><!-- vue2的<template>里必须要有一个盒子&#xff0c;不能有两个&#xff0c;这里的盒子就是 view--><view>--- v-on:click点击事件 ---<view v-on:click"onclick">{{title}}<…

Git 回顾小结

Git是一个免费开源&#xff0c;分布式的代码版本控制系统&#xff0c;版主开发团队维护代码 作用&#xff1a;记录代码内容&#xff0c;切换代码版本&#xff0c;多人开发时高校合并代码内容 Git常用命令 命令作用注意git -v查看Git版本git init初始化本地Git仓库git add 文件…

QTday5

一、客户端 二、服务器 三、配置图像处理环境 四、XMind思维导图

vscode新建vue3文件模板

输入快捷新建的名字 enter 确认后在文件中输入以下内容 {// Place your snippets for vue here. Each snippet is defined under a snippet name and has a prefix, body and// description. The prefix is what is used to trigger the snippet and the body will be expand…

无需租用云服务器:使用Linux本地搭建web服务并实现内网穿透发布公网访问的详细教程

文章目录 前言1. 本地搭建web站点2. 测试局域网访问3. 公开本地web网站3.1 安装cpolar内网穿透3.2 创建http隧道&#xff0c;指向本地80端口3.3 配置后台服务 4. 配置固定二级子域名5. 测试使用固定二级子域名访问本地web站点 前言 在web项目中,部署的web站点需要被外部访问,则…

前端自动化部署,Devops,CI/CD

DevOps 提到 Jenkins&#xff0c;想到的第一个概念就是 CI/CD 在这之前应该再了解一个概念。 DevOps Development 和 Operations 的组合&#xff0c;是一种方法论&#xff0c;并不特指某种技术或者工具。DevOps 是一种重视 Dev 开发人员和 Ops 运维人员之间沟通、协作的流程。…

Java on VS Code 8月更新|反编译器用户体验优化、新 Maven 项目工作流、代码高亮稳定性提升

作者&#xff1a;Nick Zhu 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎来到 Visual Studio Code for Java 的 8 月更新&#xff01;在这篇博客中&#xff0c;我们将为您提供有关反编译器支持的更多改进。此外&#xff0c;我们将展示如何创建没有原型的 Maven 项目以及一…

【C语言】字符函数,字符串函数,内存函数

大家好&#xff01;今天我们来学习C语言中的字符函数&#xff0c;字符串函数和内存函数。 目录 1. 字符函数 1.1 字符分类函数 1.2 字符转换函数 1.2.1 tolower&#xff08;将大写字母转化为小写字母&#xff09; 1.2.2 toupper&#xff08;将小写字母转化为大写字母&…

SpringMVC之入门

目录 1.SpringMVC工作流程 2.SpringMVC核心组件 2.1 DispatcherServlet 2.2 HandlerMapping 2.3 Handler 2.4 HandlerAdapter 2.5 ViewResolver 2.6 View 3.SpringMVC的入门 3.1 添加相关依赖 3.2 创建Spring-mvc.xml 3.3 配置web.xml 3.4 效果演示 4.静态资源处…

ios 运行ipa包 日志查看方式

方法一&#xff1a; 使用ideviceinstaller工具 # 安装ipa命令 brew install ideviceinstaller ideviceinstaller -i xxx.ipa# 查看运行日志 idevicesyslog# idevicesyslog 查找命令 idevicesyslog | grep test -A 3 -B 2 # 输出关键字所在行后3行&#xff0c;前2行) idevic…

GeoServe Web管理界面远程访问GeoServe Web管理界面的最佳工具

文章目录 前言1.安装GeoServer2. windows 安装 cpolar3. 创建公网访问地址4. 公网访问Geo Servcer服务5. 固定公网HTTP地址 前言 GeoServer是OGC Web服务器规范的J2EE实现&#xff0c;利用GeoServer可以方便地发布地图数据&#xff0c;允许用户对要素数据进行更新、删除、插入…

数据库-多表查询

概述&#xff1a; 介绍&#xff1a;多表查询&#xff1a;指从多张表中查询数据 笛卡儿积&#xff1a;笛卡儿积是指在数学中&#xff0c;两个集合&#xff08;A集合和B集合&#xff09;的所有组合情况&#xff08;在多表查询时&#xff0c;需要消除无效的笛卡儿积&#xff09; 分…

excel中的引用与查找函数篇1

1、COLUMN(reference)&#xff1a;返回与列号对应的数字 2、ROW(reference)&#xff1a;返回与行号对应的数字 参数reference表示引用/参考单元格&#xff0c;输入后引用单元格后colimn()和row()会返回这个单元格对应的列号和行号。若参数reference没有引用单元格&#xff0c;…

传输层—TCP原理详解

目录 前言 1.TCP协议 2.TCP协议段格式 3.如何解包如何分用 4.网络协议栈和文件的关系 5.如何理解TCP报头 6.TCP的特点 7.TCP字段 7.1 16位窗口大小 7.2标志位 8.超时重传 9.连接管理机制 10.滑动窗口 11.拥塞控制 12.延迟应答 13.捎带应答 14.理解TCP的面向字…

【C++】Visual Studio EditorConfig 格式设置

【C】Visual Studio EditorConfig 格式设置 文章目录 【C】Visual Studio EditorConfig 格式设置I - EditorConfig1.1 - 通用设置indent_styleindent_sizetab_widthend_of_linecharsettrim_trailing_whitespaceinsert_final_newline II - Visual Studio 特定键值缩进设置cpp_in…

蚂蚁集团SQLess 开源,与内部版有何区别?

当我们使用关系型数据库时&#xff0c;SQL 是联系起用户和数据库的一座桥梁。 SQL 是一种高度非过程化的语言&#xff0c;当我们在编写SQL 时&#xff0c;表达的是想要什么数据&#xff0c;而不是怎么获取数据。因此&#xff0c;我们往往更关心SQL 有没有满足业务逻辑&#xff…

朴素,word,任何参考文献导入endnote

朴素&#xff0c;word&#xff0c;任何参考文献导入endnote 注意&#xff1a;对于以下这几种不做阐述&#xff0c;看其他帖子都有讲述&#xff1a; 这里的参考文献指的是类似于&#xff1a; [1]. Li Y, Lu Y, Huo X, et al. Bandgap tuning strategy by cations and halide io…

如何快速搭建母婴行业的微信小程序?

如果你想为你的母婴行业打造一个独特的小程序&#xff0c;但没有任何编程经验&#xff0c;别担心&#xff01;现在有许多小程序制作平台提供了简单易用的工具&#xff0c;让你可以轻松地建立自己的小程序。接下来&#xff0c;我将为你详细介绍搭建母婴行业小程序的步骤。 首先&…