【数组】-Lc912-数组排序(冒泡、选择,快排)

写在前面

  最近想复习一下数据结构与算法相关的内容,找一些题来做一做。如有更好思路,欢迎指正。


目录

  • 写在前面
  • 一、场景描述
  • 二、具体步骤
    • 1.环境说明
    • 2.代码
  • 写在后面


一、场景描述

  给定一个长度为 n 的数组,请你编写一个函数,返回该数组按升序排序后的结果。
要求:时间复杂度 O(n^2),空间复杂度 O(n)
进阶:时间复杂度 O(nlogn),空间复杂度 O(n)

示例:
输入:[5,2,3,1,4]
返回:[1,2,3,4,5]说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。

注:本题数据范围允许绝大部分排序算法,请尝试多种排序算法的实现。

二、具体步骤

1.环境说明

名称 说明
IntelliJ IDEA 2019.2

2.代码

以下为Java版本实现:

public class Lc912_sort {

    public static void main(String[] args) {
//        int[] nums = {5, 3, 2, 4, 1};
        int[] nums = {2, 1, 4, 9};
        System.out.println(Arrays.toString(nums));

//        bubbleSort(nums);
//        selectSort(nums);
        quickSort(nums, 0 , nums.length - 1);
        System.out.println(Arrays.toString(nums));
    }


    /**
     * nlogn
     *
     * 快速排序
     *
     * 思路:递归
     * 以首元素为基准值 pivot,在给定区间[low, high], 从右向左 j 找比 pivot 小的值,从左向右 i 找比 pivot 大的值,两两交换
     * 直到 i >= j,跳出循环(此时 i 左边的都比 pivot 小)
     * 把 pivot 和 nums[i] 交换
     * 然后分别递归 基准值i 的左部分和右部分
     *
     * 通过一趟排序,得到一个基准值 pivot,左边的都比 pivot 小,右边的都比 pivot 大,然后【递归】左右
     * 注意:如果 pivot = nums[low],那么必须 j 指针先走,找到一个比 i 小的值才交换,否则会出错
     *
     * 没有返回值
     *
     * 定义 pivot = nums[low], i = low, j = high
     * while循环(i < j) i 和 j 交换
     * 1、j 从右向左,找到比 pivot 小的 while(i < j && num[j] >= pivot) j--
     * 2、i 从左向右,找到比 pivot 大的 while(i < j && nums[i] <= pivot) i++
     * 3、if (i < j) 则交换nums[i]和nums[j]的值
     *
     * 交换基准值,nums[low] = nums[i], nums[i] = pivot
     *
     * 递归左右序列
     * quickSort(nums, low, i -1)
     * quickSort(nums, i + 1, high)
     *
     * @param nums
     * @param low
     * @param high
     */
    private static void quickSort(int[] nums, int low, int high) {
        // 递归结束条件
        if (low > high) {
            return;
        }

        // 初始基准值
        int pivot = nums[low], i = low, j = high;
        while (i < j) {
            // 从右向左,找比pivot小的值
            while (i < j && nums[j] >= pivot) {
                j--;
            }

            // 从左向右,找比pivot大的值
            while (i < j && nums[i] <= pivot) {
                i++;
            }

            if (i < j) {
                int temp = nums[i];
                nums[i] = nums[j];
                nums[j] = temp;
            }
        }

        // 设置基准值
        nums[low] = nums[i];
        nums[i] = pivot;

        // 递归左右
        quickSort(nums, low, i - 1);
        quickSort(nums, i + 1, high);
    }

    /**
     * n^2
     *
     * 选择排序
     * 双层循环,直接操作原数组,没有返回值
     *
     * 思路:
     * 拿当前数,和后面的所有数比较,最终确定下来一个数
     *
     * 从左到右,拿第一个数和后面的数比较,确定的是第一个数
     * 第一层循环确定第一个数,第二层循环后面的数
     *
     * 2 层for循环
     * 第 1 层:i 的值最大到 length-2(倒数第2个元素), for (int i = 0; i < nums.length - 1; i++)
     * 第 2 层:j 的值最大到 length-1(最后1个元素),for(int j = i + 1; j < nums.length; j++)
     * 比较nums[i]与num[j]
     *
     * @param nums
     */
    private static void selectSort(int[] nums) {
        for (int i = 0; i < nums.length - 1; i ++) {
            for (int j = i + 1; j < nums.length; j++) {
                // 找出最小值,从小到大排列
                if (nums[i] > nums[j]) {
                    int temp = nums[i];
                    nums[i] = nums[j];
                    nums[j] = temp;
                }
            }
        }
    }

    /**
     * n^2
     *
     * 冒泡排序
     * 双层循环,直接操作原数组,没有返回值
     *
     * 思路:
     *
     * 两两比较,每趟能确定一个数
     * 两层for循环
     * 第一层循环控制趟数,确定第二层循环的最大值
     * 第二层循环用于比较
     *
     * 2层for循环
     * 第 1 层,i 的值为趟数(2个数1趟;3个数2趟),for(int i = 0; i < num.length -1; i++)
     * 第 2 层,j 的值最大到length-2,比较交换,for(int j = 0; j < num.length -1 -i; j++)
     * 比较 num[j]与 [j+1] 的值进行交换
     *
     * @param nums
     */
    private static void bubbleSort(int[] nums) {
        for (int i = 0; i < nums.length - 1; i++) {
            for (int j = 0; j < nums.length - 1 -i; j++) {
                // 找出最大的数,从小到大排列
                if (nums[j] > nums[j + 1]) {
                    int temp = nums[j];
                    nums[j] = nums[j + 1];
                    nums[j + 1] = temp;
                }
            }
        }
    }

}

写在后面

  如果本文内容对您有价值或者有启发的话,欢迎点赞、关注、评论和转发。您的反馈和陪伴将促进我们共同进步和成长。

你可能感兴趣的:(数据结构与算法,算法,排序算法,数据结构,java,数组)