首页 > 编程语言 >排序算法

排序算法

时间:2023-10-03 17:23:33浏览次数:45  
标签:sort right nums int 算法 static 排序 left

在线验证算法

排序数组

算法实现

1. 快排

思路

树的前序遍历。
每次选取一个数作基准值,将小于基准值的数放在左边,大于基准值的数放在右边。遍历左子树及右子树,直到只有1个数为止。

实现

class QuickSort {
    public static void sort(int[] nums) {
        shuffle(nums);
        sort(nums, 0, nums.length - 1);
    }

    public static void sort(int[] nums, int left, int right) {
        if (left >= right) return;
        int pivot = partition(nums, left, right);
        sort(nums, left, pivot - 1);
        sort(nums, pivot + 1, right);
    }

    public static int partition(int[] nums, int lo, int hi) {
        int i = lo;
        for (int j = lo; j < hi; j++) {
            if (nums[j] < nums[hi]) {
                swap(nums, i++, j);
            }
        }
        swap(nums, i, hi);
        return i;
    }

    public static void shuffle(int[] nums) {
        Random random = new Random();
        int n = nums.length;
        for (int i = 0; i < n; i++)
            swap(nums, i, random.nextInt(n - i) + i);
    }

    public static void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

2. 归并

思路

树的后序遍历。
将左子树及右子树分别排序后合并。
合并时避免多次创建临时数组,可以使用同一个临时数组。

实现

class MergeSort {

    private static int[] temp;

    public static void sort(int[] nums) {
        temp = new int[nums.length];
        sort(nums, 0, nums.length - 1);
    }

    public static void sort(int[] nums, int left, int right) {
        if (left >= right) return;
        int mid = left + (right - left) / 2;
        sort(nums, left, mid);
        sort(nums, mid + 1, right);
        merge(nums, left, mid, right);
    }

    public static void merge(int[] nums, int left, int mid, int right) {
        for (int i = left; i <= right; i++)
            temp[i] = nums[i];
        int i = left, j = mid + 1, k = left;
        while (i <= mid && j <= right) {
            if (temp[i] < temp[j]) {
                nums[k++] = temp[i++];
            } else {
                nums[k++] = temp[j++];
            }
        }
        while (i <= mid)
            nums[k++] = temp[i++];
        while (j <= right)
            nums[k++] = temp[j++];
    }

    public static void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

标签:sort,right,nums,int,算法,static,排序,left
From: https://www.cnblogs.com/kiper/p/17741324.html

相关文章

  • 归并排序算法详解
    算法介绍引用百度百科的介绍。归并排序(MergeSort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(DivideandConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表......
  • 算法:线段树
    算法:线段树哦吼!终于来学线段树啦~~拖了好久都没有敢学,主要是基础知识点不熟,代码能力太弱。但是现在已经是时候了。来看:线段树(SegmentTree)几乎是算法竞赛最常用的数据结构了,它主要用于维护区间信息(要求满足结合律)。与树状数组相比,它可以实现\(O(log⁡\n)\)的区间修改,......
  • 文心一言 VS 讯飞星火 VS chatgpt (105)-- 算法导论10.1 3题
    三、用go语言,仿照图10-2,画图表示依次执行操作ENQUEUE(Q,4)、ENQUEUE(Q,1)、ENQUEUE(Q,3)、DEQUEUE(Q)、ENQUEUE(Q,8)和DEQUEUE(Q)每一步的结果,队列初始为空,存储于数组Q[1..6]中。文心一言:在这个问题中,我们尝试使用Go语言来模拟队列的操作,并且展示每一步的结果。首先,我们需要定......
  • 文心一言 VS 讯飞星火 VS chatgpt (105)-- 算法导论10.1 3题
    三、用go语言,仿照图10-2,画图表示依次执行操作ENQUEUE(Q,4)、ENQUEUE(Q,1)、ENQUEUE(Q,3)、DEQUEUE(Q)、ENQUEUE(Q,8)和DEQUEUE(Q)每一步的结果,队列初始为空,存储于数组Q[1..6]中。文心一言:在这个问题中,我们尝试使用Go语言来模拟队列的操作,并且展示每一步的结果。首先,我们需要定义......
  • 插入排序:简单而有效的排序方法
    在计算机科学中,排序算法是一个重要且常见的主题,它们用于对数据进行有序排列。插入排序(InsertionSort)是其中一个简单但有效的排序算法。本文将详细解释插入排序的原理和步骤,并提供Java语言的实现示例。插入排序的原理及性能分析插入排序的核心思想是逐个将未排序的元素插入到已排序......
  • 记一种无需形式幂级数求逆的多点求值算法
    仅作为个人理解之用来自https://judge.yosupo.jp/submission/140699首先producttree部分不变我们考虑如何不使用形式幂级数求逆注意到如果对dft的点值求逆实际上是在对x^lim-1取模的意义下实际上在这个意义下也是可做的首先判掉所求点值在dft所用的单位根上的平凡情况(......
  • destoon 列表页面增加手动选择排序方式
    在mobile/include/mall.inc.php 行60 $order=$MOD['order'];  之前增加排序方式判断如果有order参数则$order接受参数,没有就用默认  $order=$MOD['order'];  1、增加排序以后的mobileurl函数,伪静态规则  ViewCode 伪静态规则 ViewCode  2、模......
  • P2824 [HEOI2016/TJOI2016] 排序
    针对区间排序,显然能够上值域线段树类似,但这里有个更强的做法。如果能转化成01序列,那么一个区间排序的时候,只需区间询问1的个数+区间修改就可以了。因为是排列,很清晰的二分一个mid,把大于等于它的设为1,小于它的设为0,再跑上面的算法,最后check一下询问位置是否为1即可。单调性?感性......
  • [数据结构和算法] 堆/优先队列的实现
    预备知识:完全二叉树可以用数组表示:从下标0开始存储数据:左子节点=2*父节点+1,右子节点=2*父节点+2;从下标1开始存储数据:左子结点=2*父节点,右子节点=2*父节点+1;堆:大根堆:父节点的值大于等于左右子节点的值;小根堆:父节点的值小于等于左右子节点的值;......
  • 文心一言 VS 讯飞星火 VS chatgpt (104)-- 算法导论10.1 2题
    二、用go语言,说明如何在一个数组A[1..n]中实现两个栈,使得当两个栈的元素个数之和不为n时,两者都不会发生上溢。要求PUSH和POP操作的运行时间为O(1)。文心一言:在这个问题中,我们要在一个数组A[1..n]中实现两个栈,使得当两个栈的元素个数之和不为n时,两者都不会发生上溢。这......