四种排序算法的Java实现

本文深入讲解四种经典排序算法:冒泡排序、选择排序、快速排序和插入排序。详细阐述每种算法的时间复杂度、稳定性及其实现过程。适合初学者理解和掌握排序算法的基本原理。

1、冒泡排序

 /**
     * 冒泡排序
     * 时间复杂度:O(N2)   稳定性:稳定
     *
     * @param arr
     * @return
     */
    public int[] bubbleSort(int arr[]) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[i] > arr[j]) {
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        return arr;
    }

2、选择排序

**
     * 选择排序
     * 首先初始化最小元素索引值为首元素,依次遍历待排序数列,
     * 若遇到小于该最小索引位置处的元素则刷新最小索引为该较小元素的位置,直至遇到尾元素,结束一次遍历,
     * 并将最小索引处元素与首元素交换;然后,初始化最小索引值为第二个待排序数列元素位置,
     * 同样的操作,可得到数列第二个元素即为次小元素;以此类推。
     * 时间复杂度:O(N2)   稳定性:不稳定
     *
     * @param arr
     * @return
     */
    public int[] selectSort(int arr[]) {
        for (int i = 0; i < arr.length; i++) {
            int minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }
            if (arr[i] > arr[minIndex]) {
                int temp = arr[i];
                arr[i] = arr[minIndex];
                arr[minIndex] = temp;
            }
        }
        return arr;
    }

3、快速排序

 /**
     * 快速排序
     * 类似于选择排序的定位思想)选一基准元素,依次将剩余元素中小于该基准元素的值放置其左侧,
     * 大于等于该基准元素的值放置其右侧;然后,取基准元素的前半部分和后半部分分别进行同样的处理;
     * 以此类推,直至各子序列剩余一个元素时,即排序完成(类比二叉树的思想,from up to down)
     * 时间复杂度:O(NlogN)   稳定性:不稳定
     *
     * @param arr
     * @return
     */
    public void quickSort(int arr[], int left, int right) {
        if (left < right) {
            // 找寻基准数据的正确索引
            int index = getIndex(arr, left, right);

            // 进行迭代对index之前和之后的数组进行相同的操作使整个数组变成有序
            quickSort(arr, 0, index - 1);
            quickSort(arr, index + 1, right);
        }
    }

    private int getIndex(int[] arr, int left, int right) {
        // 基准数据
        int tmp = arr[left];
        while (left < right) {
            // 当队尾的元素大于等于基准数据时,向前挪动right指针
            while (left < right && arr[right] >= tmp) {
                right--;
            }
            // 如果队尾元素小于tmp了,需要将其赋值给left
            arr[left] = arr[right];
            // 当队首元素小于等于tmp时,向前挪动left指针
            while (left < right && arr[left] <= tmp) {
                left++;
            }
            // 当队首元素大于tmp时,需要将其赋值给right
            arr[right] = arr[left];

        }
        // 跳出循环时left和right相等,此时的left或right就是tmp的正确索引位置
        // 由原理部分可以很清楚的知道left位置的值并不是tmp,所以需要将tmp赋值给arr[left]
        arr[left] = tmp;
        return left; // 返回tmp的正确位置
    }

4、插入排序

/**
     * 插入排序
     * 通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
     * 插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),
     * 因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
     * 时间复杂度:O(N2)   稳定性:稳定
     *
     * @param arr
     * @return
     */
    public int[] insertSort(int[] arr) {
        if (arr == null || arr.length == 0) {
            return arr;
        }
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = i + 1; j > 0 && arr[j] < arr[j - 1]; j--) {
                if (arr[j] < arr[j - 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
        }
        return arr;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值