Java之经典排序算法(一)

2023-11-11

一,冒泡排序

不稳定的排序算法:快希选堆
1,算法思路:

  • 比较相邻元素,如果第一个比第二个大,则交换这两个元素。
  • 从第一个元素开始依次往后比较相邻两个元素,直到最后一个比较完,这样最后一个元素就是最大的元素。
  • 再次从第一个元素开始依次往后比较相邻两个元素,最后一个元素不参与,直到倒数第二个元素比较完,这样倒数第二个元素就是第二大元素。
  • 重复上述步骤,直到最后只剩下第一个元素和第二个元素可以比较并比较完。

2,代码实现:

package com.yzd0507.Order;


//测试几种经典的排序算法
public class Sort {
	
	
	//1,冒泡排序      从小到大
	public void bubbleSort(int[] arr) {
		int len = arr.length;
		for(int i=0;i<len-1;i++) {
			for(int j=0;j<len-1-i;j++) {
				if(arr[j]>arr[j+1]) {
					int temp = arr[j+1];
					arr[j+1]=arr[j];
					arr[j]=temp;
				}
			}
		}
		
		//排序完毕  输出打印元素查看
		for(int k=0;k<len;k++) {
			System.out.println(arr[k]);
		}
	}
	

	
	public static void main(String[] args) {
		Sort sort = new Sort();
		int[] array= {12,3,2,4,66,32,9,2,43};
		sort.bubbleSort(array);
	}
}

在这里插入图片描述

二,选择排序

1,算法思路

  • 在未排序序列中找到最小的元素,放在已排序序列的第一位。
  • 在剩余未排序序列中找到最小的元素,放在已排序列的第二位。
  • 依次类推,直到只剩最后一个未排序元素,将该元素放在已排序列的最后一位。

2,代码实现

	//2,选择排序    从小到大
	public void selectSort(int[] arr) {
		int len = arr.length;
		for(int i=0;i<len-1;i++) {
			int minIndex = i;
			for(int j=i;j<len;j++) {
				if(arr[j]<arr[minIndex]) {
					minIndex = j;
				}
			}
			int temp = arr[i];
			arr[i] = arr[minIndex];
			arr[minIndex] = temp;		
		}
		
		//排序完毕    输出排序后的数组
		for(int k=0;k<len;k++) {
			System.out.println(arr[k]);
		}
	}

		int[] array= {12,3,2,4,66,32,9,2,43};
		sort.selectSort(array);

在这里插入图片描述

三,插入排序

1,算法思路

  • 从需要排序的序列中取出第一个元素作为已经排好序的元素。
  • 从需要排序的序列中取出第二个元素,从排好序的序列中最后一个元素作为当前元素开始比较,如果待排序元素小于当前元素,当前元素往后移一位。然后将当前元素指向已排序列倒数第二个元素,重新比较,直到比较完已排序序列的第一个元素或者待比较元素不小于当前元素,将待比较元素插入当前位置。
  • 重复上述步骤,直到所有元素都插入对应的位置。

2,代码实现

	//3,插入排序    从小到大
	public void insertSort(int[] arr) {
		int len = arr.length;
		for(int i=0;i<len-1;i++) {
			int curIndex=i;//当前已排好序的数组的最后一个下标
			int temp = arr[i+1];//需要插入排序的元素
			while(curIndex>=0&&temp<arr[curIndex]) {//一直比较到已排序序列的第一个元素    并且需要插入的元素小于当前比较的元素
				arr[curIndex+1]=arr[curIndex];      //从后往前比较
				curIndex--;
			}
			arr[++curIndex] = temp;                 //直到比较到第一个已排序的第一个元素  或者   不小于当前元素   此时由于curIndex--
			                                        //index已经移位到需要插入的前一位   所以需要先index+1再插入
		}
		
		//排序完毕    输出排序后的数组
		for(int k=0;k<len;k++) {
			System.out.println(arr[k]);
		}
	}

		int[] array= {12,3,2,4,66,32,9,2,43};
		sort.insertSort(array);

四,希尔排序

希尔排序是直接插入排序的一种改进版本,也称缩小增量排序。希尔排序是根据下标的增量对序列进行分组,每组内进行直接插入排序,然后逐步缩小增量,重新插入排序,直到增量缩小为1,整个序列被分为1组,插入排序,算法终止。

1,操作流程:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2,代码实现:

//4,希尔排序    从小到大
	public void shellSort(int[] arr) {
		int len = arr.length;
		for(int gap=len/2;gap>0;gap/=2) {//逐步缩小增量
			for(int i=0;i<gap;i++) {//每一个分组   i为每一个分组头下标
				
				//组内插入排序    j为每一组分组元素下标      防止数组下标越界
				for(int j=i;j<len&&j+gap<len;j=j+gap) {
					int temp = arr[j+gap];//当前需要插入排序的元素
						int curIndex=j;//当前已排好序的数组的最后一个下标
						while(curIndex>=0&&temp<arr[curIndex]) {//一直比较到已排序序列的第一个元素    并且需要插入的元素小于当前比较的元素
							arr[curIndex+gap]=arr[curIndex];      //从后往前比较   将当前元素往后移
							curIndex = curIndex-gap;//当前元素组内前移
						}
						curIndex = curIndex+gap;                //找到当前需要插入排序的元素的插入位置
						arr[curIndex] = temp;                    
				}
				
			}			
		}
		
		
		//排序完毕    输出排序后的数组
		for(int k=0;k<len;k++) {
			System.out.println(arr[k]);
		}
	}


		int[] array= {12,3,2,4,66,32,9,2,43};
		sort.shellSort(array);

五,归并排序

归并排序采用分治法,结合递归使用。

1,算法描述

  • 把长度为n的序列分成长度为n/2的子序列。
  • 将子序列再拆分,直到每个子序列中只含有一个元素。
  • 两个子序列从头开始比较,将比较结果赋给另开辟的数组temp中,全部比较完后左、右某端序列中还会剩有若干元素,将剩余的元素按原次序赋给temp(剩余的元素在上一轮归并中已经有序),再将temp中的数据复制给原序列arr对应的左+右子序列所处下标位置。
  • 当当前一级左、右子序列归并完成后,对上一级左右子序列执行同样的操作,直到最后只剩下两个子序列需要归并且归并完成。

2,操作流程:
对序列:12 , 3 , 2 ,4,66,32,9,2,43 进行归并排序,图中绿色字体为每次归并操作的数据,不同长度的红色斜线代表不同层级的分组。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3,代码实现

	//5,归并排序
	public void mergeSort(int[] arr) {
		int len = arr.length;
		sort(arr,0,len-1);//归并排序
//		for(int i=0;i<arr.length;i++) {//打印排序后的数组
//			System.out.println(arr[i]);
//		}
	}	
	public void sort(int[] arr,int left,int right) {
		if(right-left<1) {
			return;//递归退出条件     当每个元素为一组  无法再拆分时
		}
		int mid  = (left+right)/2;
		//对左边序列递归归并排序    arr包括左、右两边序列     left、mid、mid+1、right限制了操作数据位置
		sort(arr,left,mid);//原左+右原始数组    左边序列起、终下标
		//对右边序列递归归并排序
		sort(arr,mid+1,right);//原左+右原始数组    右边序列起、终下标
		//将左右两边序列合并
		merge(arr,left,mid,right);
		System.out.print("执行完一次归并后原数组中的数据:");
		for(int i=0;i<arr.length;i++) {//打印排序后的数组
			System.out.print(arr[i]+"   ");
		}
		System.out.println(" ");
		System.out.println(" ");
	}
	//将左、右两个序列合并
	public void merge(int[] arr,int left,int mid,int right) {
		//传入的left、mid、right为在最原始序列中的下标
		System.out.println("每次合并时left的下标:"+left);
		int mid1 = mid+1;
		//left为左边序列起始下标    mid为左边序列终止下标     mid2为右边序列起始下标    right为右边序列终止下标
		int[] temp = new int[right+1];//用来存放合并后的序列的临时数组     根据需要合并的right位置创造合适的长度
		System.out.println("temp的长度:"+temp.length);
		int index=left;//临时数组的下标      ???正确方式   不一定从temp数组0下标开始复制可以只在某些位置赋值   其他位置空着为默认值0   在temp数组终对应原数组位置开始复制
		//int index=0;    //???错误方式    index为左+右     右边序列合并时index是在左边序列的基础上递归增加右边序列的
		int lstart=left;//记录左边序列第一个元素的下标     ???正确方式
		//int lstart=0;//   ???错误方式   中间部分lstart并不是从0开始        是在每个分组对应位置排序    并没有单拎出来排序
		int rstart=mid1;//记录右边序列第一个元素的下标
		//1,从左、右两边序列的初始位置开始   取较小值放在temp数组中,取了值的序列起始位置后移一位  没取值的不变
	   while(lstart<=mid&&rstart<=right) {
			if(arr[lstart]<arr[rstart]) {
				temp[index]=arr[lstart++];
				//System.out.println(temp[index]);
				index++;
			}else {
				temp[index]=arr[rstart++];
				//System.out.println(temp[index]);
				index++;
			}
		}
		//2,当某一边序列全部取完后   直接将另一边剩下的数据复制给temp数组(在上一轮递归中每边序列已经拍好序)
		//以下两个if只有一个会执行
		while(lstart<=mid) {
			temp[index++]=arr[lstart++];
			//System.out.println(temp[index]);
		}
		while(rstart<=right) {
				temp[index++]=arr[rstart++];	
				//System.out.println(temp[index]);
		}
		//3,将temp中的数据复制到arr中?????    错误方式     每次仅对执行了合并操作的arr更新元素     没有执行合并操作的arr的元素不改变  并不一定从0操作
//		    //右边递归调用merge方法时是在左边的基础上操作   生成的temp长度为左+右   因此u的起始下标为left(右序列的left)
//		for(int u=0;u<temp.length;u++) {
//			arr[u]=temp[u];	
//			
//			//System.out.print(temp[u]+"    ");			
//		}
		
		System.out.print("新生成的temp数组中的数据:");
		//3,将temp中的数据复制到arr中  ???      正确方式    
		for(int u=left;u<temp.length;u++) {//结合创建temp数组长度和初始化index时   即从left位置开始复制
			arr[u]=temp[u];		
			System.out.print(temp[u]+"   ");			
		}
		System.out.println(" ");
		
	}


		int[] array= {12,3,2,4,66,32,9,2,43};
		sort.mergeSort(array);

输出结果图:
在这里插入图片描述
在这里插入图片描述
以上算法完整代码:
百度网盘提取码:g903

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java之经典排序算法(一) 的相关文章

  • 使用 java 删除 XML 根的子级

    这是我的 xml 文件
  • 无论线程如何,对象是否总是能看到其最新的内部状态?

    假设我有一个带有简单整数计数变量的可运行对象 每次可运行对象运行时该变量都会递增 该对象的一个 实例被提交以在计划的执行程序服务中定期运行 class Counter implements Runnable private int coun
  • JAVA 中的 Composer 相当于什么? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我目前从 PHP 转向 java 有没有类似的工具composer https getcomposer org 在 PHP 中用于 JAV
  • 类型已知,但方法指的是缺失类型

    我对 java 和 Eclipse 不太有经验 但遇到以下问题 我正在写类似的东西 Point3D myPoint myClass myMethod arg 我收到错误 方法 myMethod myType arg 引用缺失的类型 Poin
  • Hashset - 创建 Set 后使对象相同

    如果我们在 HashSet 中添加两个不同的对象 可变的 然后通过调用 setter 更改对象的值 使它们相同 则大小仍然是 hashSet 的 2 我无法理解其原因 public static void main String args
  • 垂直 ViewPager 中的动画

    我需要垂直制作这个动画ViewPager https www youtube com watch v wuE 4jjnp3g https www youtube com watch v wuE 4jjnp3g 这是我到目前为止所尝试的 vi
  • Java 小程序在 Mac 上闪烁

    这个问题很奇怪 问题并非在每个平台上都会发生 我在使用 MacOSX 的 Google Chrome 中出现了这种情况 但在 Safari 中却没有出现这种情况 对于使用 Windows 的朋友来说 在 Google Chrome 上运行得
  • Apache Thrift Java-Javascript 通信

    我正在编写一个基于 Apache Thrift 的 Java 服务器 它将从 Javascript 客户端接收数据 我已经完成了 Java 服务器 但问题是我可以获得 Javascript 客户端的工作示例 我无法找到一个好的示例 构建文档
  • 如何将本机数据库运算符 (postgres ~) 与 JPA 标准生成器一起使用?

    我使用 JPA 2 0 标准构建以下查询 简化 select n from notif n where n message b la 我正在使用 postgresql 数据库 我真的需要 运算符 而不是像 我可以使用与 CriteriaBu
  • 使用全局变量从内部函数获取空字符串

    请帮助我解决一些小问题 我确信你能做到 D 我试图在 firestore 文档 user cases information 上设置一个字段 其中包含一个字段 case number 首先我声明这个全局变量 private String c
  • Java Junit 测试 HTTP POST 请求

    我需要测试以下方法而不改变方法本身 该方法向服务器发出 POST 方法 但我需要制作一个独立于服务器的测试用例 在将其重定向到本地文件之前 我测试了类似的方法 但为此我将协议指定为文件 主机名指定为 localhost 端口指定为 1 我的
  • 如何自动转换十六进制代码以将其用作 Java 中的 byte[]?

    我这里有很多十六进制代码 我想将它们放入 Java 中 而不需要向每个实体附加 0x 喜欢 0102FFAB 和我必须执行以下操作 byte test 0x01 0x02 0xFF 0xAB 我有很多很长的十六进制代码 有什么办法可以自动做
  • Java 中如何验证字符串的格式是否正确

    我目前正在用 Java 编写一个验证方法来检查字符串是否是要更改为日期的几种不同格式之一 我希望它接受的格式如下 MM DD YY M DD YY MM D YY 和 M D YY 我正在测试第一种格式 每次它都告诉我它无效 即使我输入了有
  • 如何让“循环”泛型在 Java 中工作?

    我在编译以下涉及一些泛型的代码时遇到错误 public abstract class State
  • 是否可以手动检查 LocateRegistry 是否存在?

    I 已经发现 https stackoverflow com a 8338852 897090一种安全的方式获得LocateRegistry 即使注册表尚不存在 Registry registry null try registry Loc
  • 避免 @Secured 注释的重复值

    我正在尝试使用以下方法来保护我的服务方法 Secured如下 public interface IUserService Secured ROLE ROLE1 ROLE ROLE2 ResponseEntity saveUser Creat
  • Time.valueOf 方法返回错误值

    我使用 Time valueOf 方法将字符串 09 00 00 转换为 Time 对象 如下所示 Time valueOf LocalTime parse 09 00 00 当我调用 getTime 来显示我得到的值时 28800000
  • 使用 Guava Ordering 对对象列表进行多条件排序

    我有一个类无法实现可比较 但需要根据 2 个字段进行排序 我怎样才能用番石榴实现这一目标 假设班级是 class X String stringValue java util Date dateValue 我有一个清单 List
  • Java 8 方法签名不一致

    Java 8 为我们提供了具有很长签名的新方法 如下所示 static
  • 从 InputStream 中删除换行符

    我喜欢从一个文件中删除所有换行符 对于 n 和 r n java io InputStream 在读取文件时 相应的方法如下所示 param target linkplain File return linkplain InputStrea

随机推荐

  • Nginx安装和反向代理配置

    什么是反向代理 反向代理是指以代理服务器来接受internet上的连接请求 然后将请求转发给内部网络上的服务器 并将从服务器上得到的结果返回给internet上请求连接的客户端 此时代理服务器对外就表现为一个反向代理服务器 反向代理代理的是
  • 查看相关性

    查看相关性 方法一 df to csv data1 csv import matplotlib pyplot as plt import seaborn as sns 变量相关性分析 fig ax plt subplots fig set
  • 逻辑回归案例练习

    逻辑回归 场景一 在训练的初始阶段 我们将要构建一个逻辑回归模型来预测 某个学生是否被大学录取 设想你是大学相关部分的管理者 想通过查看申请学生的两次测试的评分 来决定他们是否被录取 现在你拥有之前申请学生的可以用于训练逻辑回归的训练样本集
  • 钉钉微应用接入(企业内部开发)

    文档中心 https open doc dingtalk com 钉钉后台配置 创建微应用流程 获取企业号CorpID Secret 登录钉钉OA管理后台 微应用 工作台设置 仅企业主管理员可查看 应用开发流程 注册企业 进入OA管理后台
  • 原来gdb的底层调试原理这么简单

    一 前言 这篇文章来聊聊大名鼎鼎的GDB 它的豪门背景咱就不提了 和它的兄弟GCC一样是含着金钥匙出生的 在GNU的家族中的地位不可撼动 相信每位嵌入式开发工程师都使用过gdb来调试程序 如果你说没有用过 那只能说明你的开发经历还不够坎坷
  • 【04】Unity AR 2022Vuforia——虚拟按钮超详细教程【含代码】

    04 Unity AR 2022Vuforia 虚拟按钮超详细教程 含代码 虚拟按钮超详细教程 含代码 目录 04 Unity AR 2022Vuforia 虚拟按钮超详细教程 含代码 1 前期工作 2 创建Virtual Button 3
  • Vue3-初识Vue3、创建Vue3工程、vue3组合式API(setup、ref函数、reactive函数)、响应式原理、计算属性、监视属性

    Vue3 1 目录 Vue3 1 一 Vue3简介 二 创建Vue3 0工程 1 使用vue cli创建 2 使用vite创建 三 常用的Composition API 组合式API 1 拉开序幕的setup 2 ref函数 3 react
  • Flutter沉浸式透明状态栏-flutter自定义凸起BottomAppBar导航

    注意 flutter项目默认是使用Kotlin语言 在Google I O 2017中 Google 宣布 Kotlin 取代 Java 成为 Android 官方开发语言 Kotlin详情见 https www kotlincn net
  • 异常处理--java.lang.reflect.MalformedParameterizedTypeException

    异常信息 org springframework beans factory BeanCreationException Error creating bean with name sqlSessionFactory defined in
  • C语言指针详解

    1 指针是什么 指针是内存中一个最小单元的编号 也就是地址 平时口语中说的指针 通常指的是指针变量 是用来存放内存地址的变量 所以 指针就是地址 口语中说的指针通常指的是指针变量 1 指针变量 我们可以通过 取地址操作符 取出变量的内存其实
  • 活动效果评估体系,该怎么搭建?

    如果让你来评估这次活动 你会怎么分析 无论是面试还是工作 做数据分写的同学都经常遇到这个问题 今天我们系统讲解一下 场景还原 某音乐类APP 对新用户进行一个新注册即送7天会员权益的活动 用户注册后 自主决定是否点击领取 为期1个月 问 如
  • python函数定义参数类型和返回值类型

    python中我们也可以定义函数的参数类型和返回值类型 如下代码 函数参数和返回值的类型声明 python函数类型的声明 更加有意义 更加实用一些 def add a b param a int param b int return int
  • C++ STL中map.erase(it++)用法原理解析

    之前在代码中使用map erase函数时 误搬了vector erase的用法 导致Server down掉了 好在在测试环境就及时发现了问题 在上线前进行了补救 以下总结一下map erase的正确用法 首先看一下在循环中使用vector
  • 灰灰-325-326-327-2019中南大学计算机上机-走台阶(3)

    1 n个台阶 一次走1阶或2阶 问走n阶有多少可能 1 lt n lt 1000 000 结果用1000 0000 7取模输出 输入格式 输入台阶数n 输出格式 结果用1000 0000 7取模输出 输入样例 3 输出样例 3 includ
  • 【技巧】各编辑器基础开发快捷键

    文章目录 一 IDEA 二 vim 1 各个模式的相互切换 2 正常模式 3 插入模式 4 底行模式 5 视图模式 三 Visual Studio 2017 四 PyCharm 一 IDEA psvm 回车 快速打出main函数 sout
  • docker网络自定义

    docker网络自定义 书接上回 我们认识了docker0网络以及 link参数的使用 https blog csdn net hello list article details 124815842 今天来了解下docker自定义网络 那
  • Java描述贪心算法解决背包问题

    思路 首先将物品根据性价比排好序在一个集合里 性价比 价格 重量 然后根据性价比从大到小依次依次放入背包 如果没办法放入这个物品的全部 就放入一部分 如果可以放入全量物品 就放入全量物品 Main java的代码 import java u
  • get和post区别

    get参数通过url传递 post放在post是放在请求头的包体 request body 中 因为参数直接暴露在url中 get比post更不安全 所以不能用来传递敏感信息 get请求在url中传递的参数是有长度限制的 get提交的数据最
  • 『动态规划·差分』队列

    P r o b l e m mathrm Problem Problem S o l u t i o n mathrm Solution Solution 首先考虑第一小问 问题转化为 每一行的问题互相独立 令 c j a i j a 1
  • Java之经典排序算法(一)

    一 冒泡排序 不稳定的排序算法 快希选堆 1 算法思路 比较相邻元素 如果第一个比第二个大 则交换这两个元素 从第一个元素开始依次往后比较相邻两个元素 直到最后一个比较完 这样最后一个元素就是最大的元素 再次从第一个元素开始依次往后比较相邻