自学内容网 自学内容网

Java常用排序算法

冒泡排序(Bubble Sort)

arr[0] 与 arr[1]比较,如果前面元素大就交换,如果后边元素大就不交换。然后依次arr[1]与arr[2]比较,第一轮将最大值排到最后一位。
第二轮arr.length-1个元素进行比较,将第二大元素排到倒数第二位。直到某一轮元素位置没有交换或者结束最后一轮结束排序。这是冒泡排序改良版本。
在这里插入图片描述

//冒泡排序
public void test1() {
    int[] arr = {5, 2, 8, 3, 1, 6};
    //i是冒泡次数
    for (int i = 0; i < arr.length - 1; i++) {
        //每一轮将flag设置成true,当已经排好后直接返回,不需要进行完整个循环
        boolean flag = true;
        //j需要排序的元素个数
        for (int j = 0; j < arr.length - 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;
                flag = false;
            }
        }
        if(flag == true){
            break;
        }
    }
    //arr = [1, 2, 3, 5, 6, 8]
    System.out.println("arr = " + Arrays.toString(arr));
}

选择排序(Selection Sort)

选择排序每次从待排序的元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的元素排完。
从数组中选择出最小值放在第一个,将之前第一个元素和最小值之前所在索引位交换,依次进行第二个、第三个…
在这里插入图片描述

//选择排序
public void test2() {
    int[] arr = {5, 2, 8, 3, 1, 6};
    for (int i = 0; i < arr.length - 1; i++) {
        int minIndex = i;
        for (int j = i + 1; j < arr.length; j++) {
            //当前元素与下一个元素比较,记录较小的索引
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        // 交换arr[i]和arr[minIndex]
        int temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
    //arr = [1, 2, 3, 5, 6, 8]
    System.out.println("arr = " + Arrays.toString(arr));
}

插入排序(Insertion Sort)

插入排序是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表。
第一个元素天然排序;第二个元素如果比第一个小就插入到第一个前面;第三个与第一个小就插入到第一个前面,如果比第二个小就插入到第二个前面;依次类推…
在这里插入图片描述

//插入排序
public void test3() {
    int[] arr = {5, 2, 8, 3, 1, 6};
    // 外部循环从第二个元素开始,
    // 因为我们将第一个元素视为已排序部分
    for (int i = 1; i < arr.length; i++) {
        int temp  = arr[i];
        int j = i - 1;
        // 将当前值key和前面的值进行比较,
        // 如果前面的值>key 则将值往后移1位
        while (j >= 0 && arr[j] > temp ) {
            arr[j + 1] = arr[j];
            j--;
        }
        // 在不小当前值temp的位置,插入当前值temp
        arr[j + 1] = temp;
    }
    //arr = [1, 2, 3, 5, 6, 8]
    System.out.println("arr = " + Arrays.toString(arr));
}

希尔排序(Shell Sort)

希尔排序是一种改进的插入排序算法,它的基本思想是将待排序的数组按照一定的间隔进行分组,对每组使用插入排序算法进行排序,然后缩小间隔,再对分组进行排序,直到间隔为1为止。
逐渐减小间隔大小的方法有助于提高排序过程的效率,可以减少比较和交换的次数。这是希尔排序算法的一个关键特点。

//希尔排序
public void test4() {
//第一轮比如步长为5,拿出array[i],array[i+5]...,6与5,2与7,8与9等排序后array = {6, 2, 8, 3, 1, 5,7,9,4};
//第二轮比如步长为3,第二轮拿出array[i],array[i+3]...,6与3与7,2与1与9,8与5与4,排序后array = {3, 1, 4, 6, 2, 5,7,9,8};
//第三轮比如步长为1,进行插入排序
    int[] array = {5, 2, 8, 3, 1, 6,7,9,4};
    int increment = array.length / 2;
    while (increment >= 1){
        for (int i = increment; i < array.length; i++) {
            int j = i - increment;
            int temp = array[i];
            // 寻找插入位置并移动数据
            while (j >= 0 && array[j] > temp) {
                array[j + increment] = array[j];
                j -= increment;
            }
            array[j + increment] = temp;
        }
        // 设置新的增量
        increment /= 2;
    }
    //arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    System.out.println("arr = " + Arrays.toString(array));
}

快速排序(Quick Sort)

快速排序是一种分治思想的排序算法,它的基本思想是通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,然后再分别对这两部分记录继续进行排序,以达到整个序列有序的目的。

int[] array = {5, 2, 8, 3, 1, 6,7,9,4};
第一次拿最大索引元素4,将比4大的都放后边,4小的都放前面
array = {3,1, 2,4,5,8, 6,7,9}
元素4索引位置已经确定
比4小的{3,1, 2}再以2为中心,小的排前面,大的排后边,确定了2的顺序。
因为1,32的前后,只有一个元素,也就确定了1,3顺序。
比4大的{5,8, 6,7,9}再以9为中心,依次类推...
public class Quick {
    public static void main(String[] args) {
        int[] arr = {5, 2, 8, 6, 1, 3};
        int[] expectedArr = {1, 2, 3, 5, 6, 8};
        Quick.quickSort(arr, 0, arr.length - 1);
        System.out.println("arr = " + Arrays.toString(arr));
        Assertions.assertArrayEquals(expectedArr, arr);
    }
    // 接收一个数组 arr,一个低索引 low ,和一个高索引 high 作为参数
    public static void quickSort(int[] arr, int low, int high) {
        // 检查 low 是否小于 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 枢轴所在位置
     */
    private static int partition(int[] arr, int low, int high) {
        // 将最后一个元素作为枢轴元素( arr[high] )
        int pivot = arr[high];
        // 将 i 初始化为 low - 1,用于跟踪较小元素的索引
        int i = low - 1;
        for (int j = low; j < high; j++) {
            if (arr[j] < pivot) {
                // 如果当前元素 arr[j] 小于枢轴元素,则增加 i 并交换 arr[i] 和 arr[j]
                // 较小元素索引+1
                i++;
                // 将当前元素 arr[j] 放在较小元素索引位置
                // 将较小元素放在前面
                swap(arr, i, j);
            }
            // 其他情况,则较小元素索引没有增加,说明当前元素应该放在右边
        }
        // 将枢轴元素( arr[high] )与索引 i + 1 处的元素交换。
        // 确保枢轴元素左边是较小元素,右边是较大元素
        swap(arr, i + 1, high);
        // 将 i + 1 作为枢轴索引返回
        return i + 1;
    }
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

原文地址:https://blog.csdn.net/weixin_43732943/article/details/140407106

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!