0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

排序算法有哪些

科技绿洲 来源:Java技术指北 作者:Java技术指北 2023-10-11 15:49 次阅读

1. 归并排序(递归版)

归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治策略,即分为两步:分与治。

  1. 分:先递归分解数组成子数组
  2. 治:将分阶段得到的子数组按顺序合并

我们来具体看看例子,假设我们现在给定一个数组:[6,3,2,7,1,3,5,4],我们需要使用归并算法对其排序,其大致过程如下图所示:

图片

阶段可以理解为就是递归拆分子序列的过程,递归的深度为log2n。而治的阶段则是将两个子序列进行排序的过程,我们通过图解看看治阶段最后一步中是如何将[2,3,6,7]和[1,3,4,5]这两个数组合并的。

图片

图中左边是复制的临时数组,而右边是原数组,我们将左右指针对应的值进行大小比较,将较小的那个数放入原数组中,然后将相应的指针右移。比如第一步中,我们比较左边指针L指向的4和右指针R指向的1,R指向的1小,则把1放入原数组中的第一个位置中,然后R指针向右移动。后面再继续,直到左边临时数组的元素都按序覆盖了右边的原数组。最后我们通过上图再结合源码来看看吧:

class Solution {
    public int[] sortArray(int[] nums) {
        sort(0, nums.length - 1, nums);
        return nums;
    }

    // 分:递归二分
    private void sort(int l, int r, int[] nums) {
        if (l >= r) return;

        int mid = (l + r) / 2;
        sort(l, mid, nums);
        sort(mid + 1, r, nums);
        merge(l, mid, r, nums);
    }


    // 治:将nums[l...mid]和nums[mid+1...r]两部分进行归并
    private void merge(int l, int mid, int r, int[] nums) {
        int[] aux = Arrays.copyOfRange(nums, l, r + 1);

        int lp =l, rp = mid + 1;

        for (int i = lp; i <= r; i ++) {
            if (lp > mid) {                // 如果左半部分元素已经全部处理完毕
                nums[i] = aux[rp - l];
                rp ++;
            }  else if (rp > r) {          // 如果右半部分元素已经全部处理完毕
                nums[i] = aux[lp - l];
                lp ++;
            } else if (aux[lp-l] > aux[rp - l]) {     // 左半部分所指元素 > 右半部分所指元素
                nums[i] = aux[rp - l];
                rp ++;
            } else {                                  // 左半部分所指元素 <= 右半部分所指元素
                nums[i] = aux[lp - l];
                lp ++;
            }
        }
    }
}

我们可以看到,分阶段的时间复杂度是logN,而合并阶段的时间复杂度是N,所以归并算法的时间复杂度是O(N*logN),因为每次合并都需要对应范围内的数组,所以其空间复杂度是O(N);

2. 归并排序(迭代版)

上面的归并排序是通过递归二分的方法进行数组切分的,其实我们也可以通过迭代的方法来完成这步,看下图:

图片

其因为数组,所以我们直接通过迭代从1开始合并,其中sz就是合并的长度,这种方法也可以称为自底向上的归并,其具体的代码如下

class Solution {
    public int[] sortArray(int[] nums) {
        int n = nums.length;
        // sz= 1,2,4,8 ... 排序
        for (int sz = 1; sz < n; sz *= 2) {
            // 对 arr[i...i+sz-1] 和 arr[i+sz...i+2*sz-1] 进行归并
            for (int i = 0; i < n - sz; i += 2*sz ) {
                merge(i, i + sz - 1, Math.min(i+sz+sz-1, n-1), nums);
            }
        }
        return nums;
    }

   // 和递归版一样
    private void merge(int l, int mid, int r, int[] nums) {
        int[] aux = Arrays.copyOfRange(nums, l, r + 1);

        int lp =l, rp = mid + 1;

        for (int i = lp; i <= r; i ++) {
            if (lp > mid) {
                nums[i] = aux[rp - l];
                rp ++;
            }  else if (rp > r) {
                nums[i] = aux[lp - l];
                lp ++;
            } else if (aux[lp-l] > aux[rp - l]) {
                nums[i] = aux[rp - l];
                rp ++;
            } else {
                nums[i] = aux[lp - l];
                lp ++;
            }
        }
    }
}

3. 总结

好了,归并算法就介绍完了,再来总结一下:

归并排序是一种十分高效的排序算法,其时间复杂度为O(N*logN)。归并排序的最好,最坏的平均时间复杂度均为O(nlogn),排序后相等的元素的顺序不会改变,所以也是一种稳定的排序算法。归并排序被应用在许多地方,其java中Arrays.sort()采用了一种名为TimSort的排序算法,其就是归并排序的优化版本。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • JAVA
    +关注

    关注

    19

    文章

    2980

    浏览量

    105584
  • 代码
    +关注

    关注

    30

    文章

    4857

    浏览量

    69465
  • 排序算法
    +关注

    关注

    0

    文章

    53

    浏览量

    10125
  • 数组
    +关注

    关注

    1

    文章

    418

    浏览量

    26084
收藏 人收藏

    评论

    相关推荐

    FPGA排序-冒泡排序介绍

    排序算法是图像处理中经常使用一种算法,常见的排序算法插入
    发表于 07-17 10:12 1191次阅读
    FPGA<b class='flag-5'>排序</b>-冒泡<b class='flag-5'>排序</b>介绍

    十大排序算法总结

    排序算法是最经典的算法知识。因为其实现代码短,应该广,在面试中经常会问到排序算法及其相关的问题。一般在面试中最常考的是快速
    的头像 发表于 12-20 10:39 1208次阅读

    数据结构的几个重要知识点

    线性结构、树形结构、图状结构,常用的数据结构:数组、链表、堆栈、树、图等,常用的排序算法:希尔排序、冒泡
    发表于 02-27 15:01

    算法的原理是什么?基数排序是如何实现的?

    算法的原理是什么?基数排序是如何实现的?哪几种方法可以实现基数排序
    发表于 07-05 07:42

    基于C语言的几种排序算法的分析

    排序是计算机程序设计中一项经常发生的操作,排序算法的研究其重要的理论及应用意义。文中就几种排序算法
    发表于 09-18 10:31 102次下载

    C语言教程之几种排序算法

    数据结构的排序算法很多种。 其中, 快速排序 、希尔排序、堆排序、直接选择
    发表于 11-16 10:23 1790次阅读

    基于排序学习的推荐算法

    排序学习技术尝试用机器学习的方法解决排序问题,已被深入研究并广泛应用于不同的领域,如信息检索、文本挖掘、个性化推荐、生物医学等.将排序学习融入推荐算法中,研究如何整合大量用户和物品的特
    发表于 01-16 15:50 0次下载
    基于<b class='flag-5'>排序</b>学习的推荐<b class='flag-5'>算法</b>

    常用的排序算法总览

    我们通常所说的排序算法往往指的是内部排序算法,即数据记录在内存中进行排序
    的头像 发表于 06-13 18:18 2922次阅读
    常用的<b class='flag-5'>排序</b><b class='flag-5'>算法</b>总览

    实用的排序算法 - 交换排序

    实用的排序算法 - 交换排序
    的头像 发表于 03-20 09:53 1815次阅读
    实用的<b class='flag-5'>排序</b><b class='flag-5'>算法</b> -  交换<b class='flag-5'>排序</b>

    排序算法分享:归并排序说明

    我们今天继续给大家分享排序算法里面的另外一种排序算法:归并排序
    的头像 发表于 12-24 14:34 832次阅读

    浅谈希尔排序算法思想以及如何实现

    01 希尔排序算法思想 希尔排序也是一种插入排序,是简单插入排序改进后的一个更高效版本,同时也是首批突破O(n^2)
    的头像 发表于 06-30 10:05 2103次阅读

    拓扑排序算法什么作用

    大家好,我是bigsai。 拓扑排序,很多人都可能听说但是不了解的一种算法。不知者大多会提出这样的疑问: 这是某种排序算法?这好像是一种图论算法
    的头像 发表于 09-24 10:53 6973次阅读
    拓扑<b class='flag-5'>排序</b><b class='flag-5'>算法</b><b class='flag-5'>有</b>什么作用

    排序算法的基本逻辑

    排序是数据结构与算法里面最基础最入门的内容,虽然简单,但是深入研究的话里面还是很多内容的,今天我们来全面详细的讲一讲各种排序算法的分类、原
    的头像 发表于 08-31 09:16 3456次阅读

    常见排序算法分类

    本文将通过动态演示+代码的形式系统地总结十大经典排序算法排序算法 算法分类 —— 十种常见排序
    的头像 发表于 06-22 14:49 1043次阅读
    常见<b class='flag-5'>排序</b><b class='flag-5'>算法</b>分类

    python升序和降序排序代码

    中使用它们。 排序是计算机科学中最基本的操作之一,它将一组数据按照某个特定的顺序进行排列。升序排序是将数据按照从小到大的顺序进行排列,而降序排序则是将数据按照从大到小的顺序进行排列。不同的排序
    的头像 发表于 11-21 15:20 3479次阅读