首页 > 其他分享 >排序——归并排序

排序——归并排序

时间:2024-07-13 17:27:02浏览次数:19  
标签:归并 .. int mid high low 排序

前面的文章中 我们详细介绍了排序的概念,插入排序,交换排序与选择排序,大家可以通过下面的链接再去学习:

​​​​​​排序的概念及插入排序

交换排序

选择排序

这篇文章就详细介绍一下另一种排序算法:归并排序。

一,基本概念

归并:将两个或两个以上的有序表组合成一个新有序表

2-路归并排序

排序过程

初始序列看成n个有序子序列,每个子序列长度为1

两两合并,得到 ë n/2 û 个长度为2或1的有序子序列

再两两合并,重复直至得到 一个 长度为 n 的有序序列为止

例:

将两个顺序表合成一个有序表

两个有序子序列的归并

设两个有序表存放在同一数组中相邻的位置上:R[low..mid]R[mid + 1..high]

每次分别从两个表中取出一个记录进行关键字的比较,将较小者放入T[1ow..high]

重复 此过程,直至其中一个表为空,最后将另一非空表中余下的部分直接复制到 T

在代码中实现:

void Merge(RedType R[],RedType &T[],int low,int mid,int high)
{   i=low;j=mid+1;k=low; 
   while(i<=mid&&j<=high) 	//将R中记录由小到大地并入T中
   {  if(R[i].key<=R[j].key) T[k]=R[i++]; 
      else T[k]=R[j++];    }					
   while(i<=mid) T[k++]=R[i++];	//将剩余的R[low..mid]复制到T中 
   while(j<=high) T[k++]=R[j++];//将剩余的R[j.high]复制到T中 
}

 归并排序的递归

2-路归并排序将R[low..high]中的记录归并排序后放入T[low..high]中。当序列长度等于1时,递归结束,否则:

① 将当前序列一分为二,求出分裂点mid = (low+high)/2;

② 对子序列R[low..mid]递归,结果放入S[low..mid]中;

③ 对子序列R[mid + 1..high]递归,结果放入S[mid + 1..high]中;

④ 调用算法 Merge ,将 S[ low..mid ] 和 S[mid + 1..high] 归并 T[ low..high ] 。

 具体的代码实现递归过程:

void MSort(RedType R[],RedType &T[],int low,int high)
{  if(low==high) T[low]=R[low]; 
   else
   { 
      mid=(low+high)/2;    	//将当前序列一分为二,求出分裂点mid 
      MSort(R,S,low,mid);  	//R[low..mid]递归,结果放入S[low..mid] 
      MSort(R,S,mid+1,high);//R[mid+1..high]递归,结果放入S[mid+1..high]
      Merge(S,T,low,mid,high);//将S[low..mid]和S[mid+1..high]归并到T[low..high]
   }						
} 

下面是一段完整的归并排序实例:

#include <stdio.h>

// 合并两个子数组的函数
void merge(int arr[], int l, int m, int r) {
    int i, j, k;
    int n1 = m - l + 1; // 左子数组的大小
    int n2 = r - m;     // 右子数组的大小

    int L[n1], R[n2]; // 创建临时数组

    // 复制数据到临时数组 L[] 和 R[]
    for (i = 0; i < n1; i++)
        L[i] = arr[l + i];
    for (j = 0; j < n2; j++)
        R[j] = arr[m + 1 + j];

    // 合并临时数组回 arr[l..r]
    i = 0; // 初始化第一个子数组的索引
    j = 0; // 初始化第二个子数组的索引
    k = l; // 初始化合并后的子数组的索引
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k] = L[i];
            i++;
        } else {
            arr[k] = R[j];
            j++;
        }
        k++;
    }

    // 复制 L[] 的剩余元素(如果有的话)
    while (i < n1) {
        arr[k] = L[i];
        i++;
        k++;
    }

    // 复制 R[] 的剩余元素(如果有的话)
    while (j < n2) {
        arr[k] = R[j];
        j++;
        k++;
    }
}

// 归并排序的主函数
void mergeSort(int arr[], int l, int r) {
    if (l < r) {
        int m = l + (r - l) / 2; // 计算中间点

        mergeSort(arr, l, m); // 递归排序左半部分
        mergeSort(arr, m + 1, r); // 递归排序右半部分

        merge(arr, l, m, r); // 合并左右两部分
    }
}

int main() {
    int arr[] = {12, 11, 13, 5, 6, 7};
    int arr_size = sizeof(arr) / sizeof(arr[0]);

    printf("给定的数组是 :");
    for (int i = 0; i < arr_size; i++)
        printf("%d ", arr[i]);
    printf("\n");

    mergeSort(arr, 0, arr_size - 1); // 对整个数组进行归并排序

    printf("排序后的数组是: ");
    for (int i = 0; i < arr_size; i++)
        printf("%d ", arr[i]);
    return 0;
}

算法分析

时间效率:O(nlog2n)

 空间效率:O(n)

稳 定 性:稳定


到此归并排序就结束了, 如果文章对你有用的话请点个赞支持一下吧!

标签:归并,..,int,mid,high,low,排序
From: https://blog.csdn.net/Blusher1/article/details/140396637

相关文章

  • 排序算法——选择排序法
    选择排序算法概述选择排序(SelectionSort)是一种简单直观的排序算法。它的基本思想是:在要排序的一组数中,选出最小(或最大)的一个数与第一个位置的数交换;然后在剩下的数当中再找最小(或最大)的与第二个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较......
  • mysql获取按日期排序获取最新的记录
    今天让一个数据查询难了。主要是对groupby理解的不够深入。才出现这样的情况这种需求,我想很多人都遇到过。下面是我模拟我的内容表我现在需要取出每个分类中最新的内容select*fromtestgroupbycategory_idorderby`date`结果如下:明显。这不是我想要的数据,原因是msyql......
  • LeetCode 2974. 最小数字游戏(排序)
    题目:2974.最小数字游戏思路:排序后,两个两个取出来进行操作即可classSolution{public:vector<int>numberGame(vector<int>&nums){sort(nums.begin(),nums.end());vector<int>v;for(inti=1;i<nums.size();i+=2){v.pu......
  • JDK 8 之后可以使用更加简单的方法 Stream 流来实现排序功能
    //创建并初始化ListList<Person>list=newArrayList<Person>(){{add(newPerson(1,30,"张三"));add(newPerson(2,20,"李四"));add(newPerson(3,40,"王五"));}};......
  • 希尔排序详解
    文章目录希尔排序原理排序演示1排序演示2复杂度分析时间复杂度空间复杂度稳定性希尔排序原理希尔排序(也称为缩小增量排序)采用的是分治的思想,设定一定的间隔,按照这个间隔将集合分成若干个子集合,然后对子集合进行排序;完成后减少这个间隔,再进行排序;逐渐减小这个间隔,直......
  • Java中的排序算法详解
    Java中的排序算法详解大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!1.排序算法概述排序算法是计算机科学中的基础问题,它将一组元素按照特定的顺序重新排列。在实际开发中,选择合适的排序算法可以显著提高程序的性能。2.冒泡排序(BubbleSort)冒泡排序......
  • 经典再现,回顾常见排序算法之冒泡排序,附Java源码及优化改进实现
    回顾一下排序算法,老酒装新瓶,给自己的技能点做个回放。排序(Sorting)是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个有序的序列,也可以理解为高矮个站队。衡量排序算法的两个指标,时间复杂度和稳定性。举个例子,如果我们的数据......
  • 【Oracle】SQL 将一组已经排序的数据进行分组,按照每组50行进行分组
    【Oracle】SQL将一组已经排序的数据进行分组,按照每组50行进行分组简单来说,使用ceil函数SELECTyour_column,--ROW_NUMBER()OVER(ORDERBYyour_column)为排序的开窗函数,用那种都可以CEIL(ROW_NUMBER()OVER(ORDERBYyour_column)/51)ASgroup_numberFR......
  • C# Winform之propertyGrid控件分组后排序功能
    在WinForms的PropertyGrid控件中,你可以通过多种方式对属性进行排序,包括按类别(Category)排序以及按属性名称排序。默认情况下,PropertyGrid控件会根据[Category]和[DisplayName]属性装饰器对属性进行分组和排序。如果你想要自定义排序规则,你可以通过以下几种方法:使用......
  • C++冒泡排序(使用vector动态数组)
    #include<iostream>#include<vector>usingnamespacestd;voidsort(vector<int>&a){  constintsize=a.size();  inttemp;  intflag=1;  while(flag==1)  {  flag=0;  for(inti=0;i<size;++i)  {   if(a[i]>......