Java实现常见的排序算法

2023-07-20 15:33:09 浏览数 (1)

前言

本文简单说下排序算法,比较常见的排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。

冒泡排序

冒泡排序(Bubble Sort):通过比较相邻元素的大小,将较大的元素逐渐交换到右侧,实现逐步排序。

代码语言:javascript复制
    //冒泡排序
    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;
                }
            }
        }
    }
    @Test
    void test() {
        int[] arr = {2, 5, 3, 1, 4, 6};
        mergeSort(arr);
        System.out.println("排序结果:");
        for (int j : arr) {
            System.out.print(j   " ");
        }
    }

输出:

代码语言:javascript复制
排序结果:
1 2 3 4 5 6 

该算法遍历并找到未排序部分的最小元素,并将其与当前位置的元素交换,从而逐步形成有序序列。

选择排序

选择排序(Selection Sort):每次从未排序的部分选择最小(或最大)的元素,将其放在已排序部分的末尾,逐步构建有序序列。

代码语言:javascript复制
    //选择排序
    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[minIndex];
            arr[minIndex] = arr[i];
            arr[i] = temp;
        }
    }
    @Test
    void test() {
        int[] arr = {2, 5, 3, 1, 4, 6};
        selectionSort(arr);
        System.out.println("排序结果:");
        for (int j : arr) {
            System.out.print(j   " ");
        }
    }

输出:

代码语言:javascript复制
排序结果:
1 2 3 4 5 6 

该算法遍历并找到未排序部分的最小元素,并将其与当前位置的元素交换,从而逐步形成有序序列。

插入排序

插入排序(Insertion Sort):将数组分为已排序和未排序两部分,逐个将未排序的元素插入到已排序部分的正确位置。

代码语言:javascript复制
    //插入排序
    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;
            // 将大于 key 的元素向右移动
            while (j >= 0 && arr[j] > key) {
                arr[j   1] = arr[j];
                j--;
            }
            arr[j   1] = key;
        }
    }
    @Test
    void test() {
        int[] arr = {2, 5, 3, 1, 4, 6};
        insertionSort(arr);
        System.out.println("排序结果:");
        for (int j : arr) {
            System.out.print(j   " ");
        }
    }

输出:

代码语言:javascript复制
排序结果:
1 2 3 4 5 6 

该算法将数组分为已排序和未排序两部分,将未排序部分的元素逐个插入到已排序部分的正确位置。在每次插入过程中,将大于待插入元素的元素向右移动,直到找到合适的位置。

快速排序

快速排序(Quick Sort):选择一个基准元素,将数组划分为小于基准和大于基准的两个子数组,然后递归地对子数组进行排序。

代码语言:javascript复制
   //快速排序
    public static void quickSort(int[] arr) {
        quickSort(arr, 0, arr.length - 1);
    }
    private static void quickSort(int[] arr, int low, int high) {
        if (low < high) {
            // 划分数组并获取划分点的索引
            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  ;
                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;
    }
    @Test
    void test() {
        int[] arr = {2, 5, 3, 1, 4, 6};
        quickSort(arr);
        System.out.println("排序结果:");
        for (int j : arr) {
            System.out.print(j   " ");
        }
    }

输出:

代码语言:javascript复制
排序结果:
1 2 3 4 5 6 

快速排序算法通过选择一个基准元素,将数组划分为小于基准和大于基准的两个子数组,然后递归地对子数组进行排序,最终将整个数组排序。在示例中,我们选择最右侧的元素作为基准,并使用双指针的方式进行划分和交换。

归并排序

归并排序(Merge Sort):将数组递归地分成两半,对两半分别进行排序,然后将两个有序的子数组合并成一个有序数组。是一个基于分治法思想的算法

代码语言:javascript复制
//归并排序
    public static void mergeSort(int[] arr) {
        int n = arr.length;
        int[] temp = new int[n];
        mergeSort(arr, temp, 0, n - 1);
    }
    private static void mergeSort(int[] arr, int[] temp, int low, int high) {
        if (low < high) {
            int mid = (low   high) / 2;
            mergeSort(arr, temp, low, mid);
            mergeSort(arr, temp, mid   1, high);
            merge(arr, temp, low, mid, high);
        }
    }
    private static void merge(int[] arr, int[] temp, int low, int mid, int high) {
        System.arraycopy(arr, low, temp, low, high - low   1);
        int i = low;
        int j = mid   1;
        int k = low;
        while (i <= mid && j <= high) {
            if (temp[i] <= temp[j]) {
                arr[k] = temp[i];
                i  ;
            } else {
                arr[k] = temp[j];
                j  ;
            }
            k  ;
        }
        while (i <= mid) {
            arr[k] = temp[i];
            i  ;
            k  ;
        }
    }
    @Test
    void test() {
        int[] arr = {2, 5, 3, 1, 4, 6};
        mergeSort(arr);
        System.out.println("排序结果:");
        for (int j : arr) {
            System.out.print(j   " ");
        }
    }

输出:

代码语言:javascript复制
排序结果:
1 2 3 4 5 6 

归并排序算法使用分治的思想,将数组不断地分割为较小的子数组,然后将这些子数组进行合并,最终得到有序的数组。此处使用了 System.arraycopy() 方法将待排序的数组复制到临时数组中,避免了多次复制的操作。

结尾

这里只简单的列出几个,后续更新文章会补上。


0 人点赞