java常用8大排序

Java中的八大排序算法是编程中常用的排序方法,每种排序算法都有其独特的特点和应用场景。以下是对Java八大排序算法的详细介绍:

1. 冒泡排序(Bubble Sort)

  • 基本思想:通过对待排序序列从前向后(或从后向前),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部(或使值较小的元素逐渐从前移向后部),就像水底的气泡一样逐渐向上冒。
  • 时间复杂度:O(n^2)
  • 空间复杂度:O(1)
  • 稳定性:稳定
public class BubbleSort {  public static void bubbleSort(int[] arr) {  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]) {  // 交换 arr[j+1] 和 arr[j]  int temp = arr[j];  arr[j] = arr[j+1];  arr[j+1] = temp;  }  }  }  }  public static void main(String[] args) {  int[] arr = {64, 34, 25, 12, 22, 11, 90};  bubbleSort(arr);  System.out.println("Sorted array");  for (int i = 0; i < arr.length; i++)  System.out.print(arr[i] + " ");  System.out.println();  }  
}

2. 选择排序(Selection Sort)

  • 基本思想:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余未排序元素中继续寻找最小(或最大)元素,然后放到已排序序列的末尾。以此类推,直到全部待排序的数据元素排完。
  • 时间复杂度:O(n^2)
  • 空间复杂度:O(1)
  • 稳定性:不稳定
public class SelectionSort {  public static void selectionSort(int[] arr) {  int n = arr.length;  for (int i = 0; i < n-1; i++) {  // 找到[i, n-1]区间里的最小值的索引  int minIndex = i;  for (int j = i+1; j < n; j++) {  if (arr[j] < arr[minIndex]) {  minIndex = j;  }  }  // 交换arr[i]和arr[minIndex]  int temp = arr[i];  arr[i] = arr[minIndex];  arr[minIndex] = temp;  }  }  public static void main(String[] args) {  int[] arr = {64, 25, 12, 22, 11};  selectionSort(arr);  System.out.println("Sorted array");  for (int i = 0; i < arr.length; i++)  System.out.print(arr[i] + " ");  System.out.println();  }  
}

3. 插入排序(Insertion Sort)

  • 基本思想:将一个记录插入到已经排好序的有序表中,使得被插入数的序列同样是有序的。按照此法对所有元素进行插入,直到整个序列排为有序的过程。
  • 时间复杂度:O(n^2)(平均和最坏情况),O(n)(最好情况,即数据已经有序)
  • 空间复杂度:O(1)
  • 稳定性:稳定
public class InsertionSort {  public static void insertionSort(int[] arr) {  int n = arr.length;  for (int i = 1; i < n; ++i) {  int key = arr[i];  int j = i - 1;  /* 将arr[i]插入到arr[0...i-1]中已排序的序列中 */  while (j >= 0 && arr[j] > key) {  arr[j + 1] = arr[j];  j = j - 1;  }  arr[j + 1] = key;  }  }  public static void main(String[] args) {  int[] arr = {12, 11, 13, 5, 6};  insertionSort(arr);  System.out.println("Sorted array");  for (int i = 0; i < arr.length; i++)  System.out.print(arr[i] + " ");  System.out.println();  }  
}

4. 希尔排序(Shell Sort)

  • 基本思想:也称缩小增量排序,是插入排序的一种更高效的改进版本。希尔排序通过将原来要排序的数列分割成几个子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。
  • 时间复杂度:取决于增量序列的选择,最好为O(nlogn),最坏为O(n^2)
  • 空间复杂度:O(1)
  • 稳定性:不稳定
public class ShellSort {  // 希尔排序  public static void sort(int[] arr) {  int n = arr.length;  // 初始步长  for (int gap = n / 2; gap > 0; gap /= 2) {  // 从第gap个元素开始,逐个对其所在组进行直接插入排序操作  for (int i = gap; i < n; i++) {  int temp = arr[i];  int j;  // 对每个组进行插入排序  for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {  arr[j] = arr[j - gap];  }  arr[j] = temp;  }  }  }  // 测试方法  public static void main(String[] args) {  int[] arr = {9, 8, 3, 7, 5, 6, 4, 1};  sort(arr);  System.out.println("Sorted array: ");  for (int i = 0; i < arr.length; i++) {  System.out.print(arr[i] + " ");  }  }  
}

5. 快速排序(Quick Sort)

  • 基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。
  • 时间复杂度:O(nlogn)(平均情况),O(n^2)(最坏情况,如数组已经有序)
  • 空间复杂度:O(logn)(递归栈空间)
  • 稳定性:不稳定
public class QuickSort {  // 快速排序的递归方法  public static void quickSort(int[] arr, int low, int high) {  if (low < high) {  // partitionIndex是分区后基准值的正确位置  int partitionIndex = partition(arr, low, high);  // 递归地对基准值左边的子数组进行排序  quickSort(arr, low, partitionIndex - 1);  // 递归地对基准值右边的子数组进行排序  quickSort(arr, partitionIndex + 1, high);  }  }  // 分区方法  private static int partition(int[] arr, int low, int high) {  // 选择最右边的元素作为基准值  int pivot = arr[high];  int i = (low - 1); // 小于基准值的元素的索引  for (int j = low; j < high; j++) {  // 如果当前元素小于或等于基准值  if (arr[j] <= pivot) {  i++;  // 交换arr[i]和arr[j]  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;  }  // 测试方法  public static void main(String[] args) {  int[] arr = {10, 7, 8, 9, 1, 5};  quickSort(arr, 0, arr.length - 1);  System.out.println("Sorted array: ");  for (int i = 0; i < arr.length; i++) {  System.out.print(arr[i] + " ");  }  }  
}

6. 归并排序(Merge Sort)

  • 基本思想:采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。
  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(n)(需要额外的数组来存储合并后的序列)
  • 稳定性:稳定
public class MergeSort {  // 归并排序的递归方法  public static void mergeSort(int[] arr, int left, int right) {  if (left < right) {  // 找到中间位置  int middle = left + (right - left) / 2;  // 对左半部分进行归并排序  mergeSort(arr, left, middle);  // 对右半部分进行归并排序  mergeSort(arr, middle + 1, right);  // 合并两个有序数组  merge(arr, left, middle, right);  }  }  // 合并两个有序数组的方法  private static void merge(int[] arr, int left, int middle, int right) {  // 创建临时数组来存储合并后的结果  int[] temp = new int[right - left + 1];  // 初始化两个指针,分别指向左右两个子数组的起始位置  int i = left;  int j = middle + 1;  int k = 0;  // 遍历两个子数组,将较小的元素先放入临时数组  while (i <= middle && j <= right) {  if (arr[i] <= arr[j]) {  temp[k++] = arr[i++];  } else {  temp[k++] = arr[j++];  }  }  // 如果左子数组还有剩余元素,将它们复制到临时数组  while (i <= middle) {  temp[k++] = arr[i++];  }  // 如果右子数组还有剩余元素,将它们复制到临时数组  while (j <= right) {  temp[k++] = arr[j++];  }  // 将临时数组中的元素复制回原数组  for (i = left, k = 0; i <= right; i++, k++) {  arr[i] = temp[k];  }  }  // 测试方法  public static void main(String[] args) {  int[] arr = {12, 11, 13, 5, 6, 7};  mergeSort(arr, 0, arr.length - 1);  System.out.println("Sorted array: ");  for (int i = 0; i < arr.length; i++) {  System.out.print(arr[i] + " ");  }  }  
}

7. 堆排序(Heap Sort)

  • 基本思想:是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子节点的键值或索引总是小于(或者大于)它的父节点。
  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(1)(原地排序)
  • 稳定性:不稳定
public class HeapSort {  // 堆排序  public static void sort(int[] arr) {  int n = arr.length;  // 构建最大堆  for (int i = n / 2 - 1; i >= 0; i--) {  heapify(arr, n, i);  }  // 一个个从堆顶取出元素  for (int i = n - 1; i > 0; i--) {  // 移动当前根到末尾  int temp = arr[0];  arr[0] = arr[i];  arr[i] = temp;  // 调整剩余元素,使其重新成为最大堆  heapify(arr, i, 0);  }  }  // 调整最大堆  private static void heapify(int[] arr, int n, int i) {  int largest = i; // 初始化最大为根  int left = 2 * i + 1; // 左 = 2*i + 1  int right = 2 * i + 2; // 右 = 2*i + 2  // 如果左子节点大于根  if (left < n && arr[left] > arr[largest]) {  largest = left;  }  // 如果右子节点大于目前最大  if (right < n && arr[right] > arr[largest]) {  largest = right;  }  // 如果最大不是根  if (largest != i) {  int swap = arr[i];  arr[i] = arr[largest];  arr[largest] = swap;  // 递归地调整受影响的子树  heapify(arr, n, largest);  }  }  // 测试方法  public static void main(String[] args) {  int[] arr = {12, 11, 13, 5, 6, 7};  sort(arr);  System.out.println("Sorted array: ");  for (int i = 0; i < arr.length; i++) {  System.out.print(arr[i] + " ");  }  }  
}

8. 计数排序(Counting Sort)

  • 基本思想:不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
  • 时间复杂度:O(n+k)(k是整数的范围)
  • 空间复杂度:O(k)
  • 稳定性:稳定
public class CountingSort {  // 计数排序  public static void countingSort(int[] arr) {  if (arr == null || arr.length == 0) return;  int max = arr[0];  int min = arr[0];  // 找出数组中的最大值和最小值  for (int i = 1; i < arr.length; i++) {  if (arr[i] > max) max = arr[i];  if (arr[i] < min) min = arr[i];  }  // 计数数组的长度为max-min+1,用于记录每个元素的出现次数  int[] count = new int[max - min + 1];  // 遍历待排序数组,统计每个元素的出现次数  for (int i = 0; i < arr.length; i++) {  count[arr[i] - min]++;  }  // 更改count[i],使其包含实际在arr[]中的位置信息  // 这一步是为了确保排序的稳定性  for (int i = 1; i < count.length; i++) {  count[i] += count[i - 1];  }  // 构建输出数组  int[] output = new int[arr.length];  // 反向填充目标数组,以保持稳定性  for (int i = arr.length - 1; i >= 0; i--) {  output[count[arr[i] - min] - 1] = arr[i];  count[arr[i] - min]--;  }  // 将排序后的数组复制到原数组  for (int i = 0; i < arr.length; i++) {  arr[i] = output[i];  }  }  // 测试方法  public static void main(String[] args) {  int[] arr = {4, 2, 2, 8, 3, 3, 1};  countingSort(arr);  System.out.println("Sorted array: ");  for (int i = 0; i < arr.length; i++) {  System.out.print(arr[i] + " ");  }  }  
}

这些排序算法在Java中都有广泛的应用,根据具体的数据情况和性能要求选择合适的排序算法是非常重要的。

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

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

相关文章

计算机网络基础:4.HTTP与HTTPS

一、回顾设定 想象你在经营一家繁忙的餐厅&#xff0c;顾客们通过点餐系统&#xff08;网卡&#xff09;下单&#xff0c;订单被前台&#xff08;路由器&#xff09;接收并分发到各个厨房区域&#xff08;网络设备&#xff09;。光猫像是食材供应商&#xff0c;通过高效的物流系…

在低谷中崛起:以坚韧和智慧书写人生华章

人生,犹如一场跌宕起伏的旅程,没有谁能够始终在阳光明媚的坦途上畅行无阻。无论是谁,都曾经或正在经历各自的人生至暗时刻,那是一条漫长、黝黑、阴冷、令人绝望的隧道。在这充满变数的旅途中,命运的巨浪时常会毫无征兆地袭来,将我们卷入深不见底的低谷。然而,真正决定我…

前仿xprop

xprop作用 使前仿结果更接近后仿中x态传播的情况&#xff0c;在前仿中尽早发现未初始化寄存器对电路逻辑的影响。 xprop使用 在vcs编译时&#xff0c;添加选项-xpropxprop.cfg&#xff0c;xprop.cfg为参数配置文件&#xff0c;内容如下&#xff1a; tree {test_top} {xprop…

25-无值宏与条件编译

25-无值宏与条件编译 宏是一种用于替换代码段的预处理指令。在编译阶段之前&#xff0c;预处理器会用宏的定义替换代码中的宏调用。条件编译则是一种根据条件来决定是否编译某些代码的技术。 文章目录 25-无值宏与条件编译一、无值宏二、条件编译**形式1&#xff1a;使用无值…

Conda修改包/虚拟环境储存目录

Conda修改包/虚拟环境储存目录 关键字样例 关键字 通过conda config --show [key]可以查看某个配置的值&#xff0c;[key]留空可以查看所有配置 其中&#xff1a; envs-dirs 存放虚拟环境的储存目录pkgs_dirs 包的目录 通过conda config --add [key] [value]可以为配置添加值…

Tomcat部署、优化、压力测试

目录 Tomcat概念 核心组件 Web容器 Web服务器之间解析请求的区别 Apache HTTP Server Nginx Tomcat Servlet容器 JSP容器 字节码文件 Tomcat表面处理请求的过程 Tomcat底层处理请求的过程 内部结构 Tomcat部署 JRE环境配置 PATH冒号位置的区别 安装Tomcat 目…

《峡谷小狐仙-多模态角色扮演游戏助手》复现流程

YongXie66/Honor-of-Kings_RolePlay: The Role Playing Project of Honor-of-Kings Based on LnternLM2。峡谷小狐仙--王者荣耀领域的角色扮演聊天机器人&#xff0c;结合多模态技术将英雄妲己的形象带入大模型中。 (github.com) https://github.com/chg0901/Honor_of_Kings…

[Leetcode 203][Easy]移除链表元素

目录 一、题目描述 二、整体思路 三、代码 一、题目描述 原题链接 二、整体思路 首先分成两种情况。第一种情况要先判断头元素是否要删除。第二种要在第一种基础上进行&#xff08;删除到头元素不是要删除的元素&#xff09;&#xff0c;然后遍历链表&#xff0c;遍历到不是…

大语言模型-GPT2-Generative Pre-Training2

一、背景信息&#xff1a; GPT2是2019年由OpenAI 提出的预训练语言模型。 GPT2提出语言模型式无监督的多任务学习 。旨在通过无监督学习也能达到和finetune一样的效果&#xff0c;并且拥有更强的泛化能能力。 即提出利用语言模型做下游任务时&#xff0c;不需要下游任务的任何…

美食地图开发

调用地图接口展示数据库录入的不同类别地址信息&#xff0c;提供导航服务&#xff0c;手机端电脑端自适应。 语音介绍使用微软的tts接口可选不同语音性别生成

2.2 openCv 如何使用 OpenCV 进行图像扫描、查找表操作及时间测量

目标 我们将寻找以下问题的答案: 如何遍历图像中的每一个像素?OpenCV中的矩阵值是如何存储的?如何度量我们算法的性能?我们的测试案例 让我们考虑一个简单的色彩缩减方法。由于使用无符号字符类型(C 和 C++)来存储矩阵中的项目,像素的一个通道可能有多达 256 种不同的值。…

在linux中,如何搭建nacos2.4.0的版本,修改nacos密码

由于最近服务器经常被攻击&#xff0c;看了一下发现是nacos版本过低&#xff0c;导致被抓了肉鸡&#xff0c;导致服务器的网端被跑满&#xff0c;选择重新搭建nacos&#xff0c;进入服务器后&#xff0c;首先确定服务器是否安装java&#xff0c;先执行java -version&#xff0c…

Hadoop、Hive、HBase、数据集成、Scala阶段测试

姓名&#xff1a; 总分&#xff1a;Hadoop、Hive、HBase、数据集成、Scala阶段测试 一、选择题&#xff08;共20道&#xff0c;每道0.5分&#xff09; 1、下面哪个程序负责HDFS数据存储&#xff08; C &#xff09; A. NameNode B. Jobtracher C. DataNode D. Sec…

vue3引入openlayers

安装ol包 OpenLayers作为 ol npm包提供&#xff0c;它提供了官方支持的API的所有模块。 官方地址&#xff1a;ol npm install ol模块和子模块约定 具有CamelCase名称的OpenLayers模块提供类作为默认导出&#xff0c;并且可能包含其他常量或函数作为命名导出&#xff1a; i…

Thinkphp5跨域问题常见的处理方法

在ThinkPHP5中&#xff0c;处理跨域问题通常涉及配置中间件或直接在控制器中设置响应头。以下是几种常见的解决跨域问题的方法&#xff1a; 1. 使用中间件处理跨域 你可以创建一个中间件来专门处理跨域请求。这个中间件会检查请求的来源&#xff0c;并设置相应的响应头来允许…

requests中的http连接

文章目录 前言一、安装 requests二、发送 HTTP 请求三、响应对象完整代码 前言 最近的学习内容中涉及到服务端和客户端的数据传输。主要的背景是我要从服务端获取数据&#xff0c;进行进一步的处理。前期看了一些关于Socket中TCP连接的方法&#xff0c;同样也可以进行通信。但…

vim gcc

vim 使用 vs filename 分屏 ctrl ww 切窗口 shift zz 快速提出vim vim配置 vim启动时自动读取当前用户的家目录的.vimrc文件 vim配置只影响本用户 其他用户观看同一文件不受影响 gcc指令 & c文件编译过程 动态库 静态库 & 链接方式 有相应库才能进行…

学习笔记13:怎么申请https 证书

怎么申请https 证书 申请 HTTPS 证书&#xff08;也称为 SSL/TLS 证书&#xff09;是一个涉及多个步骤的过程&#xff0c;主要目的是为网站提供安全加密和身份验证。以下是申请 HTTPS 证书的一般步骤&#xff1a; 1. 选择证书颁发机构&#xff08;CA&#xff09; 首先&#…

mysql优化面试题

目录 一、EXPLAIN 慢查询定位分析 二、SQL 语句优化 三、索引优化 四、分库分表 五、主从复制 六、缓存优化 一、EXPLAIN 慢查询定位分析 EXPLAIN 是 MySQL 提供的一个分析工具&#xff0c;用于了解查询的执行计划。通过解析 EXPLAIN 结果&#xff0c;可以识别性能瓶颈。…

全面解析 SnowNLP:中文文本处理、情感分析

1 前言 SnowNLP 是一个专门用于处理中文文本的 Python库。功能包括&#xff1a; 分词情感分析关键词提取文本分类拼音转换繁体转简体词相似度计算等 snownlp0.12.3测试环境&#xff1a;Python3.10.9 2 分词 中文分词&#xff08;Character-Based Generative Model&#xf…