Java实现十类排序算法对比展示
创始人
2025-05-31 07:53:18

Java实现排序算法

本代码展示了Java中常见的十种排序算法,并对每种算法的时间复杂度、空间复杂度、优缺点进行了说明。
代码中包含了冒泡排序、快速排序、插入排序、选择排序、希尔排序、归并排序、堆排序、计数排序、桶排序、基数排序。


import java.util.ArrayList;
import java.util.Collections;public class SortComparison {public static void main(String[] args) {int[] arr = {5, 2, 8, 4, 9, 1, 3, 7, 6, 10};long startTime1 = System.nanoTime();bubbleSort(arr.clone());long endTime1 = System.nanoTime();long duration1 = (endTime1 - startTime1);System.out.println("冒泡排序: ");for (int i : arr) {System.out.print(i + " ");}System.out.println("\n所需时间: " + duration1 + " 纳秒");long startTime2 = System.nanoTime();quickSort(arr.clone(), 0, arr.length - 1);long endTime2 = System.nanoTime();long duration2 = (endTime2 - startTime2);System.out.println("快速排序: ");for (int i : arr) {System.out.print(i + " ");}System.out.println("\n所需时间: " + duration2 + " 纳秒");long startTime3 = System.nanoTime();insertionSort(arr.clone());long endTime3 = System.nanoTime();long duration3 = (endTime3 - startTime3);System.out.println("插入排序: ");for (int i : arr) {System.out.print(i + " ");}System.out.println("\n所需时间: " + duration3 + " 纳秒");long startTime4 = System.nanoTime();selectionSort(arr.clone());long endTime4 = System.nanoTime();long duration4 = (endTime4 - startTime4);System.out.println("选择排序: ");for (int i : arr) {System.out.print(i + " ");}System.out.println("\n所需时间: " + duration4 + " 纳秒");long startTime5 = System.nanoTime();shellSort(arr.clone());long endTime5 = System.nanoTime();long duration5 = (endTime5 - startTime5);System.out.println("希尔排序: ");for (int i : arr) {System.out.print(i + " ");}System.out.println("\n所需时间: " + duration5 + " 纳秒");long startTime6 = System.nanoTime();mergeSort(arr.clone(), 0, arr.length - 1);long endTime6 = System.nanoTime();long duration6 = (endTime6 - startTime6);System.out.println("归并排序: ");for (int i : arr) {System.out.print(i + " ");}System.out.println("\n所需时间: " + duration6 + " 纳秒");long startTime7 = System.nanoTime();heapSort(arr.clone());long endTime7 = System.nanoTime();long duration7 = (endTime7 - startTime7);System.out.println("堆排序: ");for (int i : arr) {System.out.print(i + " ");}System.out.println("\n所需时间: " + duration7 + " 纳秒");long startTime8 = System.nanoTime();countingSort(arr.clone());long endTime8 = System.nanoTime();long duration8 = (endTime8 - startTime8);System.out.println("计数排序: ");for (int i : arr) {System.out.print(i + " ");}System.out.println("\n所需时间: " + duration8 + " 纳秒");long startTime9 = System.nanoTime();bucketSort(arr.clone());long endTime9 = System.nanoTime();long duration9 = (endTime9 - startTime9);System.out.println("桶排序: ");for (int i : arr) {System.out.print(i + " ");}System.out.println("\n所需时间: " + duration9 + " 纳秒");long startTime10 = System.nanoTime();radixSort(arr.clone());long endTime10 = System.nanoTime();long duration10 = (endTime10 - startTime10);System.out.println("基数排序: ");for (int i : arr) {System.out.print(i + " ");}System.out.println("\n所需时间: " + duration10 + " 纳秒");}/*** 冒泡排序* @param arr 待排序数组* 时间复杂度:O(n^2)* 空间复杂度:O(1)* 算法优点:实现简单,空间复杂度低* 算法缺点:时间复杂度高,不适用于大规模数据排序*/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]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}}/*** 快速排序* @param arr 待排序数组* @param low 起始下标* @param high 结束下标* 时间复杂度:O(nlogn)* 空间复杂度:O(logn)* 算法优点:时间复杂度低,适用于大规模数据排序* 算法缺点:实现较为复杂,空间复杂度高*/public static void quickSort(int[] arr, int low, int high) {if (low < high) {int pivot = partition(arr, low, high);quickSort(arr, low, pivot - 1);quickSort(arr, pivot + 1, high);}}/*** 分区函数* @param arr 待排序数组* @param low 起始下标* @param high 结束下标* @return 分区点下标*/public 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++;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;}/*** 插入排序* @param arr 待排序数组* 时间复杂度:O(n^2)* 空间复杂度:O(1)* 算法优点:实现简单,适用于小规模数据排序* 算法缺点:时间复杂度高,不适用于大规模数据排序*/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;while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j = j - 1;}arr[j + 1] = key;}}/*** 选择排序* @param arr 待排序数组* 时间复杂度:O(n^2)* 空间复杂度:O(1)* 算法优点:实现简单,空间复杂度低* 算法缺点:时间复杂度高,不适用于大规模数据排序*/public static void selectionSort(int[] arr) {int n = arr.length;for (int i = 0; i < n - 1; i++) {int min_idx = i;for (int j = i + 1; j < n; j++) {if (arr[j] < arr[min_idx]) {min_idx = j;}}int temp = arr[min_idx];arr[min_idx] = arr[i];arr[i] = temp;}}/*** 希尔排序* @param arr 待排序数组* 时间复杂度:O(nlogn)* 空间复杂度:O(1)* 算法优点:时间复杂度低,适用于中等规模数据排序* 算法缺点:实现较为复杂*/public static void shellSort(int[] arr) {int n = arr.length;for (int gap = n / 2; gap > 0; gap /= 2) {for (int i = gap; i < n; i += 1) {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;}}}/*** 归并排序* @param arr 待排序数组* @param l 左边界* @param r 右边界* 时间复杂度:O(nlogn)* 空间复杂度:O(n)* 算法优点:时间复杂度低,适用于大规模数据排序* 算法缺点:空间复杂度高*/public static void mergeSort(int[] arr, int l, int r) {if (l < r) {int mid = (l + r) / 2;mergeSort(arr, l, mid);mergeSort(arr, mid + 1, r);merge(arr, l, mid, r);}}/*** 归并排序辅助函数* @param arr 待排序数组* @param l 左边界* @param mid 中间点* @param r 右边界*/public static void merge(int[] arr, int l, int mid, int r) {int[] temp = new int[r - l + 1];int i = l, j = mid + 1, k = 0;while (i <= mid && j <= r) {if (arr[i] <= arr[j]) {temp[k++] = arr[i++];} else {temp[k++] = arr[j++];}}while (i <= mid) {temp[k++] = arr[i++];}while (j <= r) {temp[k++] = arr[j++];}for (int p = 0; p < temp.length; p++) {arr[l + p] = temp[p];}}/*** 堆排序* @param arr 待排序数组* 时间复杂度:O(nlogn)* 空间复杂度:O(1)* 算法优点:时间复杂度低,适用于大规模数据排序* 算法缺点:实现较为复杂*/public static void heapSort(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);}}/*** 堆排序辅助函数* @param arr 待排序数组* @param n 堆大小* @param i 根节点下标*/public static void heapify(int[] arr, int n, int i) {int largest = i;int l = 2 * i + 1;int r = 2 * i + 2;if (l < n && arr[l] > arr[largest]) {largest = l;}if (r < n && arr[r] > arr[largest]) {largest = r;}if (largest != i) {int swap = arr[i];arr[i] = arr[largest];arr[largest] = swap;heapify(arr, n, largest);}}/*** 计数排序* @param arr 待排序数组* 时间复杂度:O(n+k)* 空间复杂度:O(k)* 算法优点:时间复杂度低,适用于数据范围较小的排序* 算法缺点:数据范围过大时,空间复杂度过高*/public static void countingSort(int[] arr) {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];}}int[] count = new int[max - min + 1];for (int i = 0; i < arr.length; i++) {count[arr[i] - min]++;}int index = 0;for (int i = 0; i < count.length; i++) {while (count[i] > 0) {arr[index++] = i + min;count[i]--;}}}/*** 桶排序* @param arr 待排序数组* 时间复杂度:O(n)* 空间复杂度:O(n)* 算法优点:时间复杂度低,适用于数据范围较小的排序* 算法缺点:数据范围过大时,空间复杂度过高*/public static void bucketSort(int[] arr) {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];}}int bucketNum = (max - min) / arr.length + 1;ArrayList> bucketArr = new ArrayList<>(bucketNum);for (int i = 0; i < bucketNum; i++) {bucketArr.add(new ArrayList());}for (int i = 0; i < arr.length; i++) {int num = (arr[i] - min) / (arr.length);bucketArr.get(num).add(arr[i]);}for (int i = 0; i < bucketArr.size(); i++) {Collections.sort(bucketArr.get(i));}int index = 0;for (ArrayList arrayList : bucketArr) {for (Integer integer : arrayList) {arr[index] = integer;index++;}}}/*** 基数排序* @param arr 待排序数组* 时间复杂度:O(nk)* 空间复杂度:O(n+k)* 算法优点:时间复杂度低,适用于数据范围较小的排序* 算法缺点:数据范围过大时,空间复杂度过高*/public static void radixSort(int[] arr) {int max = arr[0];for (int i = 1; i < arr.length; i++) {if (arr[i] > max) {max = arr[i];}}for (int exp = 1; max / exp > 0; exp *= 10) {countingSort(arr, exp);}}/*** 基数排序辅助函数* @param arr 待排序数组* @param exp 指数*/public static void countingSort(int[] arr, int exp) {int[] output = new int[arr.length];int[] count = new int[10];for (int i = 0; i < arr.length; i++) {count[(arr[i] / exp) % 10]++;}for (int i = 1; i < 10; i++) {count[i] += count[i - 1];}for (int i = arr.length - 1; i >= 0; i--) {output[count[(arr[i] / exp) % 10] - 1] = arr[i];count[(arr[i] / exp) % 10]--;}for (int i = 0; i < arr.length; i++) {arr[i] = output[i];}}
}

冒泡排序

  • 时间复杂度:O(n^2)
  • 空间复杂度:O(1)
  • 稳定性:稳定
  • 特点:简单易懂,但效率较低,适用于数据量较小的情况。

排序过程:

从第一个元素开始,依次比较相邻的两个元素,如果前一个元素大于后一个元素,则交换它们的位置,直到最后一个元素。重复以上步骤,直到所有元素都排序完成。

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]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}

快速排序

  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(logn)
  • 稳定性:不稳定
  • 特点:效率高,但需要额外的空间,适用于数据量较大的情况。

排序过程:

选择一个基准元素,将小于基准元素的放在左边,大于基准元素的放在右边,然后对左右两边的子序列进行递归排序。

public static void quickSort(int[] arr, int left, int right) {if (left < right) {int i = left, j = right, x = arr[left];while (i < j) {while (i < j && arr[j] >= x) {j--;}if (i < j) {arr[i++] = arr[j];}while (i < j && arr[i] < x) {i++;}if (i < j) {arr[j--] = arr[i];}}arr[i] = x;quickSort(arr, left, i - 1);quickSort(arr, i + 1, right);}
}

插入排序

  • 时间复杂度:O(n^2)
  • 空间复杂度:O(1)
  • 稳定性:稳定
  • 特点:适用于数据量较小的情况,对于基本有序的数据效率较高。

排序过程:

从第二个元素开始,将该元素插入到已排序的序列中的正确位置,直到所有元素都排序完成。

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;while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j--;}arr[j + 1] = key;}
}

选择排序

  • 时间复杂度:O(n^2)
  • 空间复杂度:O(1)
  • 稳定性:不稳定
  • 特点:简单易懂,但效率较低,适用于数据量较小的情况。

排序过程:

从第一个元素开始,依次选择最小的元素,放在已排序序列的末尾,直到所有元素都排序完成。

public static void selectionSort(int[] arr) {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;}
}

希尔排序

  • 时间复杂度:O(nlogn) ~ O(n^2)
  • 空间复杂度:O(1)
  • 稳定性:不稳定
  • 特点:是插入排序的改进版,适用于数据量较大的情况。

排序过程:

将待排序序列按照一定的间隔分成若干个子序列,对每个子序列进行插入排序,然后逐步缩小间隔,直到间隔为1,对整个序列进行插入排序。


public static void shellSort(int[] arr) {int n = arr.length;for (int gap = n / 2; gap > 0; gap /= 2) {for (int i = gap; i < n; i++) {int j = i;int temp = arr[j];if (arr[j] < arr[j - gap]) {while (j - gap >= 0 && temp < arr[j - gap]) {arr[j] = arr[j - gap];j -= gap;}arr[j] = temp;}}}
}

归并排序

  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(n)
  • 稳定性:稳定
  • 特点:效率高,但需要额外的空间,适用于数据量较大的情况。

排序过程:

将待排序序列分成两个子序列,对每个子序列进行递归排序,然后将两个有序子序列合并成一个有序序列。

public static void mergeSort(int[] arr, int left, int right) {if (left < right) {int mid = (left + right) / 2;mergeSort(arr, left, mid);mergeSort(arr, mid + 1, right);merge(arr, left, mid, right);}
}public static void merge(int[] arr, int left, int mid, int right) {int[] temp = new int[right - left + 1];int i = left, j = mid + 1, k = 0;while (i <= mid && j <= right) {if (arr[i] <= arr[j]) {temp[k++] = arr[i++];} else {temp[k++] = arr[j++];}}while (i <= mid) {temp[k++] = arr[i++];}while (j <= right) {temp[k++] = arr[j++];}for (int p = 0; p < temp.length; p++) {arr[left + p] = temp[p];}
}

堆排序

  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(1)
  • 稳定性:不稳定
  • 特点:效率高,但需要额外的空间,适用于数据量较大的情况。

排序过程:

将待排序序列构建成一个大根堆,然后将堆顶元素与最后一个元素交换,再将前n-1个元素重新构建成一个大根堆,重复以上步骤,直到所有元素都排序完成。

public static void heapSort(int[] arr) {int n = arr.length;for (int i = n / 2 - 1; i >= 0; i--) {adjustHeap(arr, i, n);}for (int i = n - 1; i > 0; i--) {int temp = arr[0];arr[0] = arr[i];arr[i] = temp;adjustHeap(arr, 0, i);}
}public static void adjustHeap(int[] arr, int i, int length) {int temp = arr[i];for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {if (k + 1 < length && arr[k] < arr[k + 1]) {k++;}if (arr[k] > temp) {arr[i] = arr[k];i = k;} else {break;}}arr[i] = temp;
}

计数排序

  • 时间复杂度:O(n+k)
  • 空间复杂度:O(k)
  • 稳定性:稳定

排序过程:

统计待排序序列中每个元素出现的次数,然后根据元素出现的次数,将元素放入相应的位置,最终得到有序序列。

public static void countingSort(int[] arr) {int n = arr.length;if (n <= 1) {return;}int max = arr[0];for (int i = 1; i < n; i++) {if (arr[i] > max) {max = arr[i];}}int[] c = new int[max + 1];for (int i = 0; i < n; i++) {c[arr[i]]++;}for (int i = 1; i <= max; i++) {c[i] += c[i - 1];}int[] r = new int[n];for (int i = n - 1; i >= 0; i--) {int index = c[arr[i]] - 1;r[index] = arr[i];c[arr[i]]--;}for (int i = 0; i < n; i++) {arr[i] = r[i];}
}

相关内容

热门资讯

游戏服务器是什么怎么租用 游戏服务器是什么怎么租用 我是艾西,作为一个常年与游戏行业保持着高频率的服务器供应商&...
Flink-转换算子  基本转换算子         map(映射)         filter(过滤&#...
2023年金三银四大厂高频Ja... Java 面试 谈到 Java 面试,相信大家第一时间脑子里想到的词肯定是金三银四&#...
C语言手撕一个Hash表(Ha... 什么是Hash Table 散列表用的是数组支持按照下标随机访问数据的特性,所以散列表...
springMVC01- 文章目录今日目标一、SpringMVC简介1 SpringMVC概述问题导入1.1 SpringMV...
Electron开发的应用利用... 技术选型: 1、electron:21.3.3 2、electron-v...
【Elastic (ELK) ... 目录 一、ES 基本概念介绍 1.1 ES 是什么 1.2 ES 主要功能 1.3 ES 相关术语 ...
指定wb用户在指定日期范围内的... 一、操作步骤 只记录过程,不讲述原理 1.获取用户ID和cookie 用户ID在进入个...
sheng的学习笔记-IO多路... 基础概念IO分为几种:同步阻塞的BIO,同步非阻塞的NIO,...
接口自动化测试(Python+...  目录:导读 (1)接口自动化测试的优缺点 (2)Pyth...
重构条件-Consolidat... 重构条件-Consolidate Conditional Expression合并条件式二 1.合并...
【论文阅读】BiSeNet V... 前言BiSeNet V2延续了v1版本的双边结构,分别处理空间细节信息、高层语义信息。...
二、马尔可夫决策过程与贝尔曼方... 这里写目录标题1 马尔可夫性质2 马尔可夫过程3 马尔可夫奖励过程(Markov re...
golang端口重用 文章目录前言SO_REUSEADDR简介Python中的用法golang用法其他学习总结 前言 服...
Zabbix“专家坐诊”第18... 问题一 Q:Zabbix5.0版本,如图,请问这里怎么修改...
深度学习技巧应用5-神经网络中... 大家好,我是微学AI,今天给大家带来深度学习技巧应用5-神经网络中的模型...
Mongodb 常用基本语法与... 常用操作 1、 Help查看命令提示 db.help(); 2、 切换/创建数据库 use t...
java中Long型数据大小比... 起因 今天在做项目的时候,想构建一个树形结构,从数据库中查询出了所有数据...
【Linux】-- 进程概念 基本概念进程(Process):是操作系统进行资源分配的最小单位。一个进程是一个程序的一次执行过程。...
2023-03-22干活小计: transformer: position-embedding: 残差:我也会了 ad...
verilog(基础知识) 摘要:主要写自己的学习内容,可能不完整 概述 对硬件描述,主要是对芯片设计进行验证人员对其进行验证...
MySQL函数 - 字符串函数... 文章目录1 字符串函数2 数值函数3 日期函数4 流程函数 函数是指一段可以直接被另一段程序调用的程...
Word2010(详细布局解释... 目录一、界面介绍二、选项卡1、文件选项卡(保存、打开、新建、打印、保存并发送、选项&#...
ProTradex是链上衍生品... 目前,链上衍生品市场的总市值已经超过100亿美元,链上衍生品市场的产品类...
spring boot 集成 ... 要将 PostGIS 集成到 Spring Boot 应用程序中,需要按照以下步骤进行操作:1. 将...
【DDIM精读】公式推导加代码... 【DDIM精读】公式推导加代码分析。1.前言:ddim总览2.均值(μ\...
系统开发-McCabe复杂度(... 系统开发(上)-软件设计(三十二)https...
每日学术速递3.22 CV - 计算机视觉 |  ML - 机器学习 |  RL - 强化学习 | NLP 自然语言处理 ...
CCF-CSP题解 第二题(J... 目录 201312-2:ISBN号码 201403-2:窗口 20140...
在服务器上搭建nacos集群-... 搭建集群需要具备JDK环境,1个Nginx+3个nacos注册中心+1...