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

1、选择排序算法

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

2、冒泡排序算法

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

3、插入排序算法

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

4、希尔排序算法

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

5、快速排序算法

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

6、基数排序算法

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

二、代码实现方式

java 复制代码
 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);
     }
 ​
 }
复制代码
 ​
相关推荐
上元星如雨3 分钟前
详解C++的存储区
java·开发语言·c++
Wang's Blog17 分钟前
数据结构与算法之数组: LeetCode 541. 反转字符串 II (Ts版)
算法·leetcode
嵌入式学习菌44 分钟前
常见的排序算法:插入排序、选择排序、冒泡排序、快速排序
java·算法·排序算法
亥时科技44 分钟前
旅游全域体验系统(源码+文档+部署+讲解)
java·数据库·开源·旅游·源代码管理
lovebugs1 小时前
ArrayList 源码扩容机制全解析
java·后端·面试
许苑向上1 小时前
Spring MVC 拦截器(Interceptor)与过滤器(Filter)的区别?
java·spring·mvc
在成都搬砖的鸭鸭1 小时前
【LeetCode】时间复杂度和空间复杂度
算法·leetcode·golang·排序算法
Mercury_Lc1 小时前
【力扣 - 简单题】88. 合并两个有序数组
数据结构·算法·leetcode·acm
qy发大财1 小时前
全排列(力扣46)
算法·leetcode·职场和发展
欧了1111 小时前
动态规划LeetCode-1049.最后一块石头的重量Ⅱ
c语言·算法·leetcode·动态规划·01背包