深入浅出:Java 中的经典排序算法详解与实现

文章目录

1. 冒泡排序 (Bubble Sort)

基本思路
  • 通过重复遍历要排序的列表,一次比较两个元素,如果它们的顺序错误就交换它们。
  • 这个过程会重复进行直到没有更多的交换需要做,这意味着列表已经排序完成。
详细步骤
  1. 外层循环 :遍历数组的每个位置 i,表示已经进行了多少轮比较。
  2. 内层循环 :从位置 0n-1-i,比较相邻的两个元素,如果前一个元素大于后一个元素,则交换它们。
  3. 优化:如果在某一轮比较中没有发生任何交换,说明数组已经排序完成,可以提前结束排序。
Java 实现
java 复制代码
public static void bubbleSort(int[] array) {
    int n = array.length;
    boolean swapped;
    for (int i = 0; i < n - 1; i++) {
        swapped = false;
        for (int j = 0; j < n - 1 - i; j++) {
            if (array[j] > array[j + 1]) {
                // 交换数组中的两个元素
                int temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
                swapped = true;
            }
        }
        // 如果没有发生任何交换,则数组已经排序完毕
        if (!swapped) break;
    }
}

2. 插入排序 (Insertion Sort)

基本思路
  • 构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
详细步骤
  1. 外层循环:从第二个元素开始,假设前一个元素是已排序的。
  2. 内层循环:将当前元素与已排序部分的元素从后向前比较,如果已排序部分的元素大于当前元素,则将已排序部分的元素向后移动一位。
  3. 插入:找到合适的位置后,将当前元素插入到已排序部分。
Java 实现
java 复制代码
public static void insertionSort(int[] array) {
    for (int i = 1; i < array.length; i++) {
        int key = array[i];
        int j = i - 1;
        // 将大于 key 的元素向后移动
        while (j >= 0 && array[j] > key) {
            array[j + 1] = array[j];
            j--;
        }
        // 插入 key
        array[j + 1] = key;
    }
}

3. 选择排序 (Selection Sort)

基本思路
  • 每次从未排序的部分中找到最小的元素,然后将其放到已排序部分的末尾。
详细步骤
  1. 外层循环 :遍历数组的每个位置 i,表示已排序部分的末尾。
  2. 内层循环 :从位置 i+1 到数组末尾,寻找最小元素的索引 minIndex
  3. 交换元素 :如果找到的最小元素不是当前位置 i 的元素,则交换它们。
Java 实现
java 复制代码
public static void selectionSort(int[] array) {
    int n = array.length;
    for (int i = 0; i < n - 1; i++) {
        int minIndex = i;
        for (int j = i + 1; j < n; j++) {
            if (array[j] < array[minIndex]) {
                minIndex = j;
            }
        }
        if (minIndex != i) {
            int temp = array[i];
            array[i] = array[minIndex];
            array[minIndex] = temp;
        }
    }
}

4. 快速排序 (Quick Sort)

基本思路
  • 采用分治策略,选择一个基准元素,将数组分成两部分,左边的元素都小于基准,右边的元素都大于基准,然后递归地对这两部分进行排序。
详细步骤
  1. 选择基准:选择数组中的某个元素作为基准。
  2. 分区:重新排列数组,使得所有比基准小的元素都放在基准前面,所有比基准大的元素都放在基准后面。
  3. 递归排序:对左右两部分分别递归地进行快速排序。
Java 实现
java 复制代码
public static void quickSort(int[] array, int low, int high) {
    if (low < high) {
        int pi = partition(array, low, high);
        quickSort(array, low, pi - 1);  // 对左子数组排序
        quickSort(array, pi + 1, high); // 对右子数组排序
    }
}

private static int partition(int[] array, int low, int high) {
    int pivot = array[high];  // 选择最后一个元素作为基准
    int i = (low - 1);        // 指向小于基准的最后一个元素
    for (int j = low; j < high; j++) {
        if (array[j] < pivot) {
            i++;
            // 交换 array[i] 和 array[j]
            int temp = array[i];
            array[i] = array[j];
            array[j] = temp;
        }
    }
    // 交换 array[i+1] 和 array[high] (或 pivot)
    int temp = array[i + 1];
    array[i + 1] = array[high];
    array[high] = temp;
    return i + 1;
}

5. 归并排序 (Merge Sort)

基本思路
  • 采用分治策略,将数组分成两半,递归地对这两半进行排序,然后合并这两个有序数组以形成最终的排序数组。
详细步骤
  1. 分割数组:将数组分成两半,递归地对这两半进行归并排序。
  2. 合并数组:将两个有序数组合并成一个有序数组。
Java 实现
java 复制代码
public static void mergeSort(int[] array, int left, int right) {
    if (left < right) {
        int middle = (left + right) / 2;
        mergeSort(array, left, middle);   // 对左半部分排序
        mergeSort(array, middle + 1, right); // 对右半部分排序
        merge(array, left, middle, right);  // 合并两个有序部分
    }
}

private static void merge(int[] array, int left, int middle, int right) {
    int n1 = middle - left + 1;
    int n2 = right - middle;

    // 创建临时数组
    int[] L = new int[n1];
    int[] R = new int[n2];

    // 复制数据到临时数组
    for (int i = 0; i < n1; ++i)
        L[i] = array[left + i];
    for (int j = 0; j < n2; ++j)
        R[j] = array[middle + 1 + j];

    // 合并临时数组
    int i = 0, j = 0;
    int k = left;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            array[k] = L[i];
            i++;
        } else {
            array[k] = R[j];
            j++;
        }
        k++;
    }

    // 复制剩余的元素
    while (i < n1) {
        array[k] = L[i];
        i++;
        k++;
    }

    while (j < n2) {
        array[k] = R[j];
        j++;
        k++;
    }
}

测试代码

为了验证这些排序算法的正确性,可以编写一个测试程序:

java 复制代码
public class SortingAlgorithms {

    public static void main(String[] args) {
        int[] array = {64, 25, 12, 22, 11};

        System.out.println("原始数组:");
        printArray(array);

        // 调用不同的排序算法
        bubbleSort(array);
        System.out.println("冒泡排序后的数组:");
        printArray(array);

        int[] array2 = {64, 25, 12, 22, 11};
        insertionSort(array2);
        System.out.println("插入排序后的数组:");
        printArray(array2);

        int[] array3 = {64, 25, 12, 22, 11};
        selectionSort(array3);
        System.out.println("选择排序后的数组:");
        printArray(array3);

        int[] array4 = {64, 25, 12, 22, 11};
        quickSort(array4, 0, array4.length - 1);
        System.out.println("快速排序后的数组:");
        printArray(array4);

        int[] array5 = {64, 25, 12, 22, 11};
        mergeSort(array5, 0, array5.length - 1);
        System.out.println("归并排序后的数组:");
        printArray(array5);
    }

    public static void printArray(int[] array) {
        for (int value : array) {
            System.out.print(value + " ");
        }
        System.out.println();
    }
}

输出

运行上述代码,输出将会是:

原始数组:
64 25 12 22 11 
冒泡排序后的数组:
11 12 22 25 64 
插入排序后的数组:
11 12 22 25 64 
选择排序后的数组:
11 12 22 25 64 
快速排序后的数组:
11 12 22 25 64 
归并排序后的数组:
11 12 22 25 64 

希望这些详细的解释和实现对你有所帮助!如果有更多问题或需要进一步的帮助,请随时提问。

相关推荐
paterWang几秒前
小程序-基于java+SpringBoot+Vue的经济新闻资讯设计与实现
java·spring boot·小程序
ModelBulider6 分钟前
十四、SpringMVC的执行流程
java·开发语言·后端·spring·springmvc
_extraordinary_20 分钟前
选择排序+快速排序递归版(二)
算法
sp_fyf_202422 分钟前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-04
人工智能·神经网络·算法·机器学习·语言模型·数据挖掘
喜欢猪猪24 分钟前
Spring Boot开箱即用可插拔实现过程演练与原理剖析
java·spring boot·后端
MisterZhang66628 分钟前
java中rag使用mysql作为向量数据库,存储读写如何优化
java·数据库·mysql
CC大煊29 分钟前
【设计模式】模板方法模式 在java中的应用
java·设计模式·模板方法模式
Wils0nEdwards32 分钟前
Leetcode 回文数
算法·leetcode·职场和发展
可可可可可人33 分钟前
leetCode——二进制手表
算法·leetcode
兔兔爱学习兔兔爱学习34 分钟前
leetcode219. Contains Duplicate II
javascript·数据结构·算法