快速排序+归并排序(简单回顾&java)

快速排序

分析

快速排序简单来说就是分治递归。

首先将一个值确定为中枢值pivot(一般取第一个),然后小于pivot的放左边,大于pivot的放右边。

接着再对左右两边区间进行同样的操作。

代码

public class QuickSort {

    /**
     * 快速排序的入口方法。
     *
     * @param nums 要排序的数组
     */
    public void quickSort(int[] nums) {
        quickSort(nums, 0, nums.length - 1); // 从数组的第一个元素开始排序
    }

    /**
     * 快速排序的递归实现。
     *
     * @param nums 要排序的数组
     * @param left 子数组的起始索引
     * @param right 子数组的结束索引
     */
    private void quickSort(int[] nums, int left, int right) {
        if (left < right) { // 当子数组至少有两个元素时才进行排序
            int pivot = partition(nums, left, right); // 找到分区点
            quickSort(nums, left, pivot - 1); // 递归地对左侧子数组进行排序
            quickSort(nums, pivot + 1, right); // 递归地对右侧子数组进行排序
        }
    }

    /**
     * 分区函数,用于将小于基准值的元素移动到左边,大于基准值的元素移动到右边。
     *
     * @param nums 要排序的数组
     * @param left 子数组的起始索引
     * @param right 子数组的结束索引
     * @return 分区后基准元素的位置
     */
    private int partition(int[] nums, int left, int right) {
        int pivot = nums[left]; // 选择第一个元素作为基准值
        int i = left; // 设置一个指针 i 指向基准值
        for (int j = left + 1; j <= right; j++) { // 从第二个元素开始遍历
            if (nums[j] < pivot) { // 如果当前元素小于基准值
                swap(nums, ++i, j); // 将当前元素交换到比基准值小的区域
            }
        }
        swap(nums, left, i); // 最后将基准值放到正确的位置上
        return i; // 返回基准值的位置
    }

    /**
     * 交换数组中的两个元素。
     *
     * @param nums 要交换元素的数组
     * @param i 第一个元素的索引
     * @param j 第二个元素的索引
     */
    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

归并排序

分析

快速排序是先划分区域再接着往下拆,而归并排序就是往下一直拆,合并的时候再排序。

代码

class MergeSort {

    /**
     * 归并排序的入口方法。
     *
     * @param nums 要排序的数组
     */
    public void mergeSort(int[] nums) {
        mergeSort(nums, 0, nums.length - 1); // 从数组的第一个元素开始排序
    }

    /**
     * 归并排序的递归实现。
     *
     * @param nums  要排序的数组
     * @param left  子数组的起始索引
     * @param right 子数组的结束索引
     */
    public void mergeSort(int[] nums, int left, int right) {
        if (left < right) { // 当子数组至少有两个元素时才进行排序
            int center = (left + right) / 2; // 计算中间位置
            mergeSort(nums, left, center); // 对左半边进行排序
            mergeSort(nums, center + 1, right); // 对右半边进行排序
            merge(nums, left, center, right); // 合并两个已排序的子数组
        }
    }

    /**
     * 合并两个已排序的子数组。
     *
     * @param nums   原数组
     * @param left   左子数组的起始索引
     * @param center 中间索引,左子数组的最后一个元素的下一个索引
     * @param right  右子数组的结束索引
     */
    public void merge(int[] nums, int left, int center, int right) {
        int len = right - left + 1; // 计算临时数组的长度
        int[] tmp = new int[len]; // 创建临时数组用于合并
        int index = 0; // 临时数组的索引
        int start1 = left; // 左子数组的起始索引
        int start2 = center + 1; // 右子数组的起始索引

        // 合并两个子数组中的元素
        while (start1 <= center && start2 <= right) {
            if (nums[start1] < nums[start2]) { // 如果左子数组的当前元素小于右子数组的当前元素
                tmp[index++] = nums[start1++]; // 将左子数组的当前元素放入临时数组,并移动左子数组的索引
            } else {
                tmp[index++] = nums[start2++]; // 否则将右子数组的当前元素放入临时数组,并移动右子数组的索引
            }
        }

        // 处理剩余的元素
        while (start1 <= center) { // 如果左子数组还有剩余元素
            tmp[index++] = nums[start1++]; // 将剩余元素依次放入临时数组
        }
        while (start2 <= right) { // 如果右子数组还有剩余元素
            tmp[index++] = nums[start2++]; // 将剩余元素依次放入临时数组
        }

        // 将临时数组中的元素复制回原数组
        index = 0;
        while (index < len) {
            nums[left + index] = tmp[index]; // 将临时数组中的元素复制回原数组
            index++;
        }
    }
}

(by 归忆)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

归忆_AC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值