首页 > 编程语言 >数据结构与算法 --- 排序算法(二)

数据结构与算法 --- 排序算法(二)

时间:2023-08-13 18:33:08浏览次数:36  
标签:归并 排序 int --- merge 算法 数组 数据结构

title: 数据结构与算法 --- 排序算法(二)
category: 数据结构与算法
tags: 算法
updatedAt: 2023-05-18T15:29:17.847Z
createdAt: 2023-05-13T14:43:31.656Z

引言

上一篇数据结构与算法 --- 排序算法(一)中,学习了冒泡排序,插入排序,选择排序这三种时间复杂度为 \(O(n^2)\) 的算法。实时上 \(O(n^2)\) 时间复杂度是非常高的,所以一般只适合小规模数据排序,那接下来,就在看一看时间复杂度为 \(O(nlog)\) 的算法:归并排序和快速排序。

分治算法思想

归并排序和快速排序的核心思想就是分治算法思想,所以先介绍一下分治算法思想:

分治算法思想简单来说就是将一个复杂的问题分解成几个较简单的子问题,再递归地解决这些子问题。通常遵循以下三个步骤:

  • 分解:将问题分解成几个较小的子问题,这些子问题必须是相同类型的问题,且解决这些子问题必须可以解决原问题。

  • 解决:递归地解决各个子问题,如果子问题足够小可以直接解决则解决,否则继续分解。

  • 合并:将子问题的解合并为原问题的解。

归并排序

归并排序(Merge Sort)是一种基于分治思想的排序算法。它的基本思路是将待排序的数组分成两个子序列,然后对每个子序列进行递归排序,最后将排好序的两个子序列合并成一个有序序列。

算法图解

来看一下归并排序的执行过程如下图:

image.png

接下来考虑如何使用C#代码实现一个归并排序算法?

一般归并排序就是通过递归实现的,那么在数据结构与算法 --- 递归(一)中总结了递归代码的编写技巧:写递推公式,寻找终止条件,最后将递推公式翻译为代码。

那么看一下归并排序的递归代码的递推公式为:

\[merge\_sort(p,r)=merge(merge(p,q),merge(q+1,r)), \quad (p<q<r) \]

其终止条件为:\(p\ge r\)。

公式中 $ merge_sort(p,r) $ 表示对下标从 \(p\) 到 \(r\) 的数组数据进行归并排序,然后将这个问题拆分成了两个子问题: \(merge(p,q)\) 和 \(merge(q+1,r)\) ,其中下标 \(q\) 表示 \(p\) 到 \(r\) 的中间位置,也就是\(\frac{p+r}{2}\),当这两个子数组排好序之后,再将这两个有序子数组合并(\(merge()\)),就完成了该数组的排序。

这里还需要着重讲解一下两个有序子数组的合并,实际上一般在这里合并方法使用的是双指针法,双指针法是合并两个有序数组最高效的算法,其时间复杂度为 \(O(m+n)\),其中 m 和 n 分别是两个数组的长度。
具体实现步骤如下:

  1. 定义两个指针 i 和 j,分别指向两个有序数组的起始位置。
  2. 定义一个空数组 temp,用于存储合并后的有序数组。
  3. 比较两个指针所指的元素大小,将较小的元素加入 temp 数组中,并将对应的指针向后移动一位。
  4. 重复步骤 3,直到其中一个指针超出了数组的范围。
  5. 将另一个数组中剩余的元素加入 temp 数组中。
  6. 最后将temp中的元素拷贝回arr中,完成排序。

综上,用C#代码实现一个归并算法如下:

public static void MergeSort(int[] arr, int left, int right)
{
    if (left < right)
    {
        int mid = (left + right) / 2;
        //将待排序的数组分成两个子序列进行递归排序
        MergeSort(arr, left, mid);
        
        MergeSort(arr, mid + 1, right);
        //合并
        Merge(arr, left, mid, right);
    }
}

public static void Merge(int[] arr, int left, int mid, int right)
{
    //双指针法合并数据到temp数组
    int i = left, j = mid + 1, k = 0;
    
    int[] temp = new int[right - left + 1];
    
    while (i <= mid && j <= right)
    {
        if (arr[i] <= arr[j])
        {
            temp[k] = arr[i];
            i++;
        }
        else
        {
            temp[k] = arr[j];
            j++;
        }
        k++;
    }
    //当一边遍历完成后,将另一边剩余元素直接放入temp。
    while (i <= mid)
    {
        temp[k] = arr[i];
        i++;
        k++;
    }
    while (j <= right)
    {
        temp[k] = arr[j];
        j++;
        k++;
    }
    for (int p = 0; p < k; p++)
    {
        arr[left + p] = temp[p];
    }
}

标签:归并,排序,int,---,merge,算法,数组,数据结构
From: https://www.cnblogs.com/pandefu/p/17536269.html

相关文章

  • 无涯教程-Perl - ref函数
    描述如果EXPR为引用,则此函数返回真值;如果未提供EXPR,则为$_。返回的实际值还定义了引用所引用的实体的类型。内置类型为-REFSCALARARRAYHASHCODEGLOBLVALUEIO::Handle如果使用bless()函数为变量设置了祝福,则将返回新的数据类型。新的数据类型通常将是一个类名。语......
  • C语言中的排序算法及其实现方法
    C语言中的排序算法及其实现方法排序算法是计算机科学中的重要部分,它们在数据处理和算法设计中起着关键作用。在C语言编程开发中,掌握不同的排序算法及其实现方法对于提高代码质量和性能至关重要。本文将围绕C语言中的排序算法展开讨论,介绍几种常见的排序算法及其实现方法。1C语言中......
  • C语言中的排序算法及其实现方法
    C语言中的排序算法及其实现方法排序算法是计算机科学中的重要部分,它们在数据处理和算法设计中起着关键作用。在C语言编程开发中,掌握不同的排序算法及其实现方法对于提高代码质量和性能至关重要。本文将围绕C语言中的排序算法展开讨论,介绍几种常见的排序算法及其实现方法。1C语言......
  • WPF 入门笔记 - 07 - MVVM示例
    滴咚,大家好久不见......
  • 定时任务查询通道狂暴超时,原因竟然是取数据不当----清扫100年前纽约街头马粪的不是清
    本文首发于我的公众号[发现问题就解决,是低效的方式,得探究根源]、【100年前的纽约街头,市民以马车为出行工具,问题来了】 我们支付系统有个定时任务,就是将系统里所有付款中的交易,调用第三方银行查单接口,然后持久化更新付款状态。 许多同学都做过类似的定时调度程序吧。 近......
  • 暑假牛客多校第八场 2023-8-11(H、K)
    H.Insert1,Insert2,Insert3,...算法:栈做法:   我们分析题目发现每个区间的左端点一定是\(1\),而且每个新加入的数\(x\)一定是匹配最靠近它的且未经匹配的\(x-1\)。举个例子,在[1,1,2,2,3]中我们加入一个数\(3\)时由于从左到右的第二个\(2\)是已经和第一个......
  • 【8月摸鱼计划】Air780E|物联网模组|AT命令|MQTT接入|云平台(1)-MQTT基本原理及AT步骤
    基础资料基于Air780E开发板:Air780E文档中心简介:AT开发探讨重点AT固件是通信模组或者单片机(MCU)+网络模块标准固件的基本配置,该模式定制化程序较高,简单易上手,但缺点也较为明显,仅用于快速基本功能验证。本系列主要探讨MQTT方式手动接入、信息订阅及发布的基本原理,后续详细介绍接入多......
  • 【HIVE系列】01-HIVE 常用操作
    title:【HIVE系列】01-HIVE常用操作date:2018-11-1320:20:31update:2018-11-1517:10:43categories:-大数据技术-hivetags:[hive]参考资料:https://blog.csdn.net/wisgood/article/details/17376393http://ju.outofmemory.cn/entry/1764081.数据库操作(增删......
  • 牛客sql-计算用户的平均次日留存率
    参考大佬题解做一下记录:https://blog.nowcoder.net/n/fe24f96a26f1437da19e91ab1d035b03?f=commenthttps://blog.nowcoder.net/n/dd3d75ce08e3485c95bafe3c23668fc2?f=comment https://www.runoob.com/sql/sql-dates.htmlDATE_ADD(date,intervalexprtype) date参数是合......
  • dp-双调欧几里德旅行商问题
    双调欧几里德旅行商问题目录双调欧几里德旅行商问题问题描述分析递推关系程序算法导论3rd-15.3问题描述平面上n个点,确定一条连接各点的最短闭合旅程。这个解的一般形式为NP的(在多项式时间内可以求出)J.L.Bentley建议通过只考虑双调旅程(bitonictour)来简化问题,这种旅程即......