Java常见排序算法及代码实现

1、选择排序算法

选择排序(Selection Sort)是一种简单直观的排序算法,它的工作原理是每次从未排序部分选择最小(或最大)的元素,将其放到已排序部分的末尾。

2、冒泡排序算法

冒泡排序(Bubble Sort)是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。遍历数列的工作是重复进行的,直到没有再需要交换的元素为止。

3、插入排序算法

插入排序的基本思想是将待排序序列分为已排序区间和未排序区间,然后每次从未排序区间取出一个元素,将其插入到已排序区间的合适位置中,使得插入后仍然保持已排序区间有序。重复这个过程,直到未排序区间为空,整个序列有序为止。

4、希尔排序算法

Java希尔排序算法是一种基于插入排序的排序算法,通过将整个数组分成若干个子序列来进行排序,这些子序列是由数组元素的下标间隔一个固定的增量d所形成的。然后,对每一个子序列分别进行插入排序,使得整个序列基本有序。随着算法的进行,逐渐减小增量d的值,直到d为1时,整个数组就变为一个子序列,此时再对整个数组进行一次插入排序,即可完成排序。

5、快速排序算法

Java快速排序算法是一种高效的排序算法,它基于分治法的思想,通过递归地将数组分成较小的子数组进行排序,最终合并得到有序的数组。快速排序的基本思想是选择一个“基准”元素,然后将数组分成两个子数组,其中一个子数组的所有元素都比基准元素小,另一个子数组的所有元素都比基准元素大。接着,递归地对这两个子数组进行快速排序,直到子数组的大小为1或0,即已经有序。最后,合并这些有序的子数组,得到整个有序数组。

6、基数排序算法

基数排序(Radix Sort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别进行排序。又称桶排序(Bucket Sort),是一种分配式排序。它将所有待比较数值(通常为正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序,直到最高位排序完成,数列就变成一个有序序列。

二、代码实现方式

 package com.test;
 ​
 import java.util.Arrays;
 ​
 public class SortDemo {
     public static void main(String[] args) {
         int[] arr = { 64, 34, 25, 12, 22, 11, 90 };
         bubbleSort(arr);
         System.out.println("排序后的数组: ");
         for (int i : arr) {
             System.out.print(i + " ");
         }
     }
 ​
     // 1、选择排序
     /*
      * 选择排序的基本思想是:在未排序序列中,找到最小(或最大)的元素,存放到已排序序列的末尾。
      * 随着遍历的进行,每次选出的元素都比它前面的元素大(或小)。
      * 时间复杂度:O(n^2),其中n是数组的长度。空间复杂度:O(1)。
      */
     public static void selectionSort(int[] arr) {
         System.out.println("--选择排序--");
         int n = arr.length;
         for (int i = 0; i < n - 1; i++) {
             int minIndex = i;
             for (int j = i + 1; j < n; j++) {
                 if (arr[j] < arr[minIndex]) {
                     minIndex = j;
                 }
             }
             // 将最小元素与当前元素交换
             int temp = arr[i];
             arr[i] = arr[minIndex];
             arr[minIndex] = temp;
         }
     }
 ​
     // 2、冒泡排序
     /**
      * 1、比较相邻的元素,如果第一个比第二个大,就交换他们两个
      * 2、对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。这步做完了后,最后的元素就是最大的数
      * 3、针对所有的元素重复以上的步骤,除了最后一个
      * 4、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较
      * 5、重复步骤2到4,直到所有元素都排好序了。
      * 6、冒泡排序的时间复杂度是O(n^2),其中n是数组的长度。
      */
     public static void bubbleSort(int[] arr) {
         System.out.println("--冒泡排序--");
         int n = arr.length;
         for (int i = 0; i < n - 1; i++) {
             for (int j = 0; j < n - i - 1; j++) {
                 if (arr[j] > arr[j + 1]) {
                     // 交换元素
                     int temp = arr[j];
                     arr[j] = arr[j + 1];
                     arr[j + 1] = temp;
                 }
             }
         }
     }
 ​
     // 3、插入排序
     /*
      * 将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是末排序序列。
      * 从头到尾一次扫描末排序序列,将扫描到的每一个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,
      * 则将待插入元素插入到相等元素的后面)
      */
     /*
      * 插入排序的时间复杂度为O(n^2),其中n是待排序序列的长度。在最坏情况下,插入排序的时间复杂度为O(n^2)。在最好情况下,插入排序的时间复杂度为O
      * (n),其中n是待排序序列的长度。在最坏的情况下,插入排序的空间复杂度为O(1)。
      */
     public static void insertionSort(int[] arr) {
         System.out.println("--插入排序--");
         int n = arr.length;
         for (int i = 1; i < n; i++) {
             int key = arr[i];
             int j = i - 1;
             while (j >= 0 && arr[j] > key) {
                 arr[j + 1] = arr[j];
                 j -= 1;
             }
             arr[j + 1] = key;
         }
     }
 ​
     // 4、希尔排序
     /*
      * 希尔排序是一种插入排序的改进版本,它通过分组进行比较和交换,从而减少比较次数。
      * 希尔排序的基本思想是:首先将数组分成若干个子数组,然后对每个子数组进行插入排序。接着,将子数组的大小减半,重复上述过程,直到整个数组有序。
      * 希尔排序是一种高效的排序算法,适用于数据量较大的情况。
      * 
      * 时间复杂度:O(nlogn),其中n是数组的长度。空间复杂度:O(logn)。
      */
     public static void shellSort(int[] arr) {
         System.out.println("--希尔排序--");
         int n = arr.length;
         for (int gap = n / 2; gap > 0; gap /= 2) {
             for (int i = gap; i < n; i++) {
                 int temp = arr[i];
                 int j;
                 for (j = i - gap; j >= 0 && arr[j] > temp; j -= gap) {
                     arr[j + gap] = arr[j];
                 }
                 arr[j + gap] = temp;
             }
         }
     }
 ​
     // 5、快速排序
     /*
      * 从数列中挑出一个元素,称为 “基准”(pivot);
      * 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,
      * 该基准就处于数列的中间位置,这个称为分区(partition)操作;
      * 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
      */
     public static void quickSort(int[] arr, int low, int high) {
         if (low < high) {
             int pi = partition(arr, low, high);
             quickSort(arr, low, pi - 1);
             quickSort(arr, pi + 1, high);
         }
     }
 ​
     // 分区函数
     private static int partition(int[] arr, int low, int high) {
         int pivot = arr[high];
         int i = (low - 1); // 指向小于pivot的元素的位置
         for (int j = low; j <= high - 1; j++) {
             if (arr[j] < pivot) {
                 i++;
                 int temp = arr[i];
                 arr[i] = arr[j];
                 arr[j] = temp;
             }
         }
         int temp = arr[i + 1];
         arr[i + 1] = arr[high];
         arr[high] = temp;
         return (i + 1);
     }
 ​
     // 6、基数排序
     /*
      * 基数排序是一种非比较排序算法,它通过将整数按位(个、十、百等)分组来实现排序。基数排序的时间复杂度在平均情况下为O(n log r),其中n是数组的长度,r是基数的数量。
      */
     public static void radixSort(int[] arr) {
         int max = Arrays.stream(arr).max().getAsInt();
         for (int exp = 1; max / exp > 0; exp *= 10) {
             countSort(arr, exp);
         }
     }
 ​
     private static void countSort(int[] arr, int exp) {
         int n = arr.length;
         int[] output = new int[n];
         int[] count = new int[10];
         for (int i = 0; i < n; i++) {
             count[(arr[i] / exp) % 10]++;
         }
         for (int i = 1; i < 10; i++) {
             count[i] += count[i - 1];
         }
         for (int i = n - 1; i >= 0; i--) {
             output[count[(arr[i] / exp) % 10] - 1] = arr[i];
             count[(arr[i] / exp) % 10]--;
         }
         System.arraycopy(output, 0, arr, 0, n);
     }
 ​
 }
 ​

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【全球人口数据集】全球人口密度数据集GPWv4

目录 数据概述数据处理方法数据下载参考GPWv4: Population Density, Revision 11 是由 NASA Socioeconomic Data and Applications Center (SEDAC) 提供的全球人口密度数据集,旨在支持社会经济和环境研究。 数据概述 Gridded Population of the World, Version 4 (GPWv4): Po…

PyTorch 中 `torch.cuda.amp` 相关警告的解决方法

在最近的写代码过程中&#xff0c;遇到了两个与 PyTorch 的混合精度训练相关的警告信息。这里随手记录一下。 警告内容 警告 1: torch.cuda.amp.autocast FutureWarning: torch.cuda.amp.autocast(args...) is deprecated. Please use torch.amp.autocast(cuda, args...) i…

NLP面试之-激活函数

一、动机篇 1.1 为什么要有激活函数&#xff1f; 数据角度&#xff1a;由于数据是线性不可分的&#xff0c;如果采用线性化&#xff0c;那么需要复杂的线性组合去逼近问题&#xff0c;因此需要非线性变换对数据分布进行重新映射;线性模型的表达力问题&#xff1a;由于线性模型…

四、自然语言处理_08Transformer翻译任务案例

0、前言 在Seq2Seq模型的学习过程中&#xff0c;做过一个文本翻译任务案例&#xff0c;多轮训练后&#xff0c;效果还算能看 Transformer作为NLP领域的扛把子&#xff0c;对于此类任务的处理会更为强大&#xff0c;下面将以基于Transformer模型来重新处理此任务&#xff0c;看…

关于conda换镜像源,pip换源

目录 1. 查看当前下载源2. 添加镜像源2.1清华大学开源软件镜像站2.2上海交通大学开源镜像站2.3中国科学技术大学 3.删除镜像源4.删除所有镜像源&#xff0c;恢复默认5.什么是conda-forge6.pip换源 1. 查看当前下载源 conda config --show channels 如果发现多个 可以只保留1个…

因果机器学习(CausalML)前沿创新思路

结合了传统因果推断与机器学习的因果机器学习是目前AI领域的前沿研究方向&#xff0c;其核心优势在于将因果逻辑融入数据驱动模型&#xff0c;从根本上解决了传统方法的缺陷。因此&#xff0c;它也是突破传统机器学习瓶颈的关键方向&#xff0c;不仅当下热度高&#xff0c;在未…

网络防御高级02-综合实验

web页面&#xff1a; [FW]interface GigabitEthernet 0/0/0 [FW-GigabitEthernet0/0/0]service-manage all permit 需求一&#xff0c;接口配置&#xff1a; SW2: [Huawei]sysname SW2 1.创建vlan [sw2]vlan 10 [sw2]vlan 20 2.接口配置 [sw2]interface GigabitEther…

【devops】 Git仓库如何fork一个私有仓库到自己的私有仓库 | git fork 私有仓库

一、场景说明 场景&#xff1a; 比如我们Codeup的私有仓库下载代码 放入我们的Github私有仓库 且保持2个仓库是可以实现fork的状态&#xff0c;即&#xff1a;Github会可以更新到Codeup的最新代码 二、解决方案 1、先从Codeup下载私有仓库代码 下载代码使用 git clone 命令…

一竞技瓦拉几亚S4预选:YB 2-0击败GG

在2月11号进行的PGL瓦拉几亚S4西欧区预选赛上,留在欧洲训练的YB战队以2-0击败GG战队晋级下一轮。双方对阵第二局:对线期YB就打出了优势,中期依靠卡尔带队进攻不断扩大经济优势,最终轻松碾压拿下比赛胜利,以下是对决战报。 YB战队在天辉。阵容是潮汐、卡尔、沙王、隐刺、发条。G…

ATF系统安全从入门到精通

CSDN学院课程连接&#xff1a;https://edu.csdn.net/course/detail/39573

Linux内核实时机制x - 中断响应测试 Cyclictest分析1

Linux内核实时机制x - 中断响应测试Cyclitest 1 实时性测试工具 rt-test 1.1 源码下载 1.下载源码&#xff1a; ~/0-code/5.15$ git clone git://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git 正克隆到 rt-tests... remote: Enumerating objects: 5534, done. remot…

实现限制同一个账号最多只能在3个客户端(有电脑、手机等)登录(附关键源码)

如上图&#xff0c;我的百度网盘已登录设备列表&#xff0c;有一个手机&#xff0c;2个windows客户端。手机设备有型号、最后登录时间、IP等。windows客户端信息有最后登录时间、操作系统类型、IP地址等。这些具体是如何实现的&#xff1f;下面分别给出android APP中采集手机信…

如何获取,CPU,GPU,硬盘,网卡,内存等硬件性能监控与各项温度传感器

首先需要下载 OpenHardwareMonitorServer 这是一个基于OpenHardwareMonitor 的 Web 服务器。可以让任何语言都可以获取硬件信息和值&#xff0c;OpenHardwareMonitorServer 是没有UI界面的因此它可以当成控制台程序使用。 该程序可用参数如下 参数&#xff1a;需要管理员权限…

解锁大语言模型潜能:KITE 提示词框架全解析

大语言模型的应用日益广泛。然而&#xff0c;如何确保这些模型生成的内容在AI原生应用中符合预期&#xff0c;仍是一个需要不断探索的问题。以下内容来自于《AI 原生应用开发&#xff1a;提示工程原理与实战》一书&#xff08;京东图书&#xff1a;https://item.jd.com/1013604…

C++STL容器之map的使用及复现

map 1. 关联式容器 vector、list、deque、forward_list(C11) 等STL容器&#xff0c;其底层为线性序列的数据结构&#xff0c;里面存储的是元素本身&#xff0c;这样的容器被统称为序列式容器。而 map、set 是一种关联式容器&#xff0c;关联式容器也是用来存储数据的&#xf…

网络工程师 (30)以太网技术

一、起源与发展 以太网技术起源于20世纪70年代&#xff0c;最初由Xerox公司的帕洛阿尔托研究中心&#xff08;PARC&#xff09;开发。最初的以太网采用同轴电缆作为传输介质&#xff0c;数据传输速率为2.94Mbps&#xff08;后发展为10Mbps&#xff09;&#xff0c;主要用于解决…

30天开发操作系统 第 20 天 -- API

前言 大家早上好&#xff0c;今天我们继续努力哦。 昨天我们已经实现了应用程序的运行, 今天我们来实现由应用程序对操作系统功能的调用(即API, 也叫系统调用)。 为什么这样的功能称为“系统调用”(system call)呢&#xff1f;因为它是由应用程序来调用(操作)系统中的功能来完…

Java面试题及答案整理( 2023年 6 月最新版,持续更新)

秋招金九银十快到了&#xff0c;发现网上很多Java面试题都没有答案&#xff0c;所以花了很长时间搜集整理出来了这套Java面试题大全~ 这套互联网 Java 工程师面试题包括了&#xff1a;MyBatis、ZK、Dubbo、EL、Redis、MySQL、并发编程、Java面试、Spring、微服务、Linux、Spri…

查询语句来提取 detail 字段中包含 xxx 的 URL 里的 commodity/ 后面的数字串

您可以使用以下 SQL 查询语句来提取 detail 字段中包含 oss.kxlist.com 的 URL 里的 commodity/ 后面的数字串&#xff1a; <p><img style"max-width:100%;" src"https://oss.kxlist.com//8a989a0c55e4a7900155e7fd7971000b/commodity/20170925/20170…

管式超滤膜分离技术都可以应用到哪些行业?

管式超滤膜分离技术由于其高效、稳定和适应性强的特点&#xff0c;在多个行业都有广泛的应用&#xff1a; 1. 生物制药与医药行业 纯化与浓缩&#xff1a;在生物药品的下游处理阶段&#xff0c;管式超滤膜被用来纯化抗体、疫苗、蛋白质等生物大分子&#xff0c;通过精确筛选分子…