【面试刷题】两种排序算法

【面试刷题】两种排序算法

一、快速排序

1、思路步骤

  • 选取中心轴pivot。
  • 将小于Pivot,大于pivot的两个值进行交换。
  • 对pivot左半部分,pivot右半部分再次进行上述步骤。

2、LeetCode-912.排序数组

image-20220113134357954

3、代码实现

class Solution {
    public int[] sortArray(int[] nums) {
        //进行异常处理
        if (nums == null || nums.length == 0)
            return nums;
        
        quickSort(nums, 0, nums.length-1);

        return nums;
    }

    private void quickSort(int[] nums, int start, int end) {
        //处理输入
        if (start >= end) return;

        //初始化
        int left = start;
        int right = end;

        //选取pivot
        int pivot = nums[(start + end) / 2];

        //循环处理
        while (left <= right) {
            while (left <= right && nums[left] < pivot) 
                left++;
            while (left <= right && nums[right] > pivot)
                right--;
            //找到了一个left和right需要调换
            if (left <= right) {
                int temp = nums[left];
                nums[left] = nums[right];
                nums[right] = temp;
                left++;
                right--;
            }
        }

        //处理左和右,由于此时left已经大于了right,所以如下
        quickSort(nums, start, right);
        quickSort(nums, left, end);
    }
}

此处要注意,循环处理时候的left<=right是小于等于,如果是小于,可能会发生栈溢出的情况(会产生交集)如:3、2、1、4、5。

二、归并排序

1、思路详解

归并排序,递归分治。

思路详解

image-20220113140405248

2、代码实现

class Solution {
    public int[] sortArray(int[] nums) {
        //进行异常处理
        if (nums == null || nums.length == 0)
            return nums;
        
        int[] temp = new int[nums.length];
        mergeSort(nums, 0, nums.length-1, temp);

        return nums;
    }

    private void mergeSort(int[] nums, int start, int end, int[] temp) {
        if (start >= end)
            return;
        
        //先把数组拆分,分治的分。
        mergeSort(nums, start, (start + end) / 2, temp);
        mergeSort(nums, (start + end) / 2 + 1, end, temp);
        merge(nums, start, end, temp);
    }

    private void merge(int[] nums, int start, int end, int[] temp) {
        int mid = (start + end) / 2;
        int leftIndex = start;
        int rightIndex = mid + 1;
        int index = leftIndex;

        //将左边部分和右边部分放入temp
        while (leftIndex <= mid && rightIndex <= end) {
            if (nums[leftIndex] < nums[rightIndex]){
                temp[index++] = nums[leftIndex++];
            } else {
                temp[index++] = nums[rightIndex++];
            }
        }

        //存在左边和右边部分还有剩余的情况
        while (leftIndex <= mid) {
            temp[index++] = nums[leftIndex++];
        }

        while (rightIndex <= end) {
            temp[index++] = nums[rightIndex++];
        }

        //这一步很关键,注意是start和end,而不是0和nums.length,因为这是分治,是最小的两个单元。
        for (int i = start; i <= end; i++){
            nums[i] = temp[i];
        }
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值