C++实现的归并排序算法详解

 更新时间:2017年05月11日 08:53:21   作者:难免有错_  
这篇文章主要介绍了C++实现的归并排序算法,结合实例形式详细分析了归并排序算法的原理、实现步骤、操作技巧与使用方法,需要的朋友可以参考下

本文实例讲述了C++实现的归并排序算法。分享给大家供大家参考,具体如下:

归并排序

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法。
该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;
即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

归并过程

1、比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到temp[k]中,并令i和k分别加上1;
2、否则将第二个有序表中的元素a[j]复制到temp[k]中,并令j和k分别加上1.
3、如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。

归并排序的算法我们通常用递归实现,先把待排序区间[first, last]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[first,last]。

归并操作的工作原理

第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾,将另一序列剩下的所有元素直接复制到合并序列尾。

算法复杂度

时间复杂度为O(nlogn) 这是该算法中最好、最坏和平均的时间性能。
空间复杂度为 O(n)
比较操作的次数介于(nlogn) / 2和nlogn - n + 1。
赋值操作的次数是(2nlogn)。
归并排序比较占用内存,但却是一种效率高且稳定的算法。

算法C++代码

//合并两个序列
void mergeArray(int arr[], int first, int mid, int last, int temp[])
{
  int i = first;
  int j = mid + 1;
  int m = mid ;
  int n = last;
  int k = 0;
  while (i <= m && j<=n)
  {
    if (arr[i] <= arr[j])
      temp[k++] = arr[i++];
    else
      temp[k++] = arr[j++];
  }
  while (i <= m)
    temp[k++] = arr[i++];
  while (j <= n)
    temp[k++] = arr[j++];
  for (i = 0; i < k; i++)
    arr[first + i] = temp[i];
}
void mySort(int arr[], int first, int last, int temp[])
{
  if (first < last)
  {
    int mid = (first + last) / 2;
    mySort(arr, first, mid, temp);
    mySort(arr, mid+1, last, temp);
    mergeArray(arr, first, mid, last, temp);
  }
}
bool mergeSort(int arr[], int len)
{
  int*p = new int[len];
  if (NULL == p)
    return false;
  mySort(arr, 0, len - 1, p);
  delete[] p;
  return true;
}

算法测试

#include <iostream>
using namespace std;
//上述归并排序源码
int main()
{
  int arr[] = { 2, 23, 32, 34, 45, 6, 5, 65, 7, 6, 87, 87, 8, 798, 34, 35, 46, 45, 65, 756, 876, 8, 7, 87, 87, 5, 34, 344, 3, 32 };
  int len = sizeof(arr) / sizeof(int);
  mergeSort(arr, len);
  for (int i = 0; i < len; i++)
    cout << arr[i] << " ";
  cout << endl;
  system("pause");
}

运行结果:

2 3 5 5 6 6 7 7 8 8 23 32 32 34 34 34 35 45 45 46 65 65 87 87 87 87 344 756 798 876
请按任意键继续. . .

希望本文所述对大家C++程序设计有所帮助。

相关文章

  • c语言 字符串转大写的简单实例

    c语言 字符串转大写的简单实例

    这篇文章主要介绍了c语言 字符串转大写的简单实例,有需要的朋友可以参考一下
    2013-12-12
  • 浅析C++中的函数重载

    浅析C++中的函数重载

    这篇文章主要介绍了浅析C++中的函数重载,在C++中,可以为两个或两个以上的函数提供相同的函数名称,只要参数类型不同,或者参数类型相同而参数个数不同,又或者参数类型参数个数相同,参数次序不同,称为函数重载,需要的朋友可以参考下
    2023-08-08
  • C++实现动态顺序表(vector)

    C++实现动态顺序表(vector)

    这篇文章主要为大家详细介绍了C++实现动态顺序表,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • c++实现加载so动态库中的资源

    c++实现加载so动态库中的资源

    下面小编就为大家带来一篇c++实现加载so动态库中的资源。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12
  • C++实现播放音频的示例详解

    C++实现播放音频的示例详解

    这篇文章主要为大家详细介绍了C++如何利用第三方库实现播放音频的功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • C++Vector容器常用函数接口详解

    C++Vector容器常用函数接口详解

    最近我学习了C++中的STL库中的vector容器,对于常用容器,我们不仅要会使用其常用的函数接口,我们还有明白这些接口在其底层是如何实现的。所以特意整理出来一篇博客供我们学习
    2022-08-08
  • 在QT5中实现求两个输入值的和并输出(实例)

    在QT5中实现求两个输入值的和并输出(实例)

    下面小编就为大家带来一篇在QT5中实现求两个输入值的和并输出(实例)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • QT出现没有MySQL驱动手动编译详细步骤

    QT出现没有MySQL驱动手动编译详细步骤

    这篇文章主要给大家介绍了关于QT出现没有MySQL驱动手动编译详细步骤的相关资料,文中通过图文介绍的非常详细,对大家学习或者使用QT具有一定的参考学习价值,需要的朋友可以参考下
    2023-04-04
  • C++ auto自动类型推导规则和使用详解

    C++ auto自动类型推导规则和使用详解

    C++11 赋予 auto 关键字新的含义,使用它来做自动类型推导。也就是说,使用了 auto 关键字以后,编译器会在编译期间自动推导出变量的类型,这样我们就不用手动指明变量的数据类型了
    2022-08-08
  • C语言课程设计之抽奖系统

    C语言课程设计之抽奖系统

    这篇文章主要为大家详细介绍了C语言课程设计之抽奖系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12

最新评论