c++归并排序详解

C++归并排序详解

归并排序是一种基于分治思想的高效排序算法,它的时间复杂度为O(nlogn),并且它的稳定性使得它在实际应用中得到了广泛的应用。在本文中,我们将为大家详细讲解C++归并排序的具体实现过程和算法思想。

算法原理

归并排序基于分治算法,首先将待排序序列不断二分,直到每个子序列只剩一个元素,然后将相邻的子序列进行归并,合并后的子序列再次进行归并,最终得到有序序列。

简单来说,归并排序可以概括为以下三个步骤:

  1. 分割:将待排序序列不断二分,直到每个子序列只剩一个元素。
  2. 归并:将相邻的子序列进行归并,合并后的子序列再次进行归并。
  3. 合并:最终得到有序的序列。

代码实现

下面是C++中归并排序的具体实现:

void merge(vector<int>& nums, int start, int mid, int end) {
    int left = start, right = mid + 1;
    vector<int> temp;
    while (left <= mid && right <= end) {
        if (nums[left] <= nums[right])
            temp.push_back(nums[left++]);
        else
            temp.push_back(nums[right++]);
    }
    while (left <= mid)
        temp.push_back(nums[left++]);
    while (right <= end)
        temp.push_back(nums[right++]);
    for (int i = 0; i < temp.size(); ++i) 
        nums[start + i] = temp[i];
}

void mergeSort(vector<int>& nums, int start, int end) {
    if (start >= end) return;
    int mid = (start + end) / 2;
    mergeSort(nums, start, mid);
    mergeSort(nums, mid + 1, end);
    merge(nums, start, mid, end);
}

归并排序的主要部分是归并操作,也就是merge函数。mergeSort函数用于划分子序列和递归调用归并操作,其中start表示待排序序列的起始位置,end表示终止位置,mid表示中间位置。在merge函数中,定义temp用于临时存储归并后的结果,在循环中依次将两个子序列的元素进行比较,将较小的元素依次存入temp中,最终将剩余的元素直接插入到temp中,然后将temp中的元素拷贝回原数组中。

示例说明

示例一

看下面这个例子,假设我们有一个数组[6,8,4,3,9,1,7,2,5]需要进行排序。

  1. 分割:首先整个数组被分为[6,8,4,3][9,1,7,2,5]两个子序列,然后两个子序列再分别被分割为[6,8][4,3][9,1,7][2,5]两个子序列,最终分为[6][8][4][3][9][1][7][2][5]这九个独立的子序列。
  2. 归并:将相邻子序列归并,首先将[6][8]两个子序列进行合并,得到[6,8],继续将[3][4]进行合并,得到[3,4],然后将[6,8][3,4]进行合并,得到[3,4,6,8]。同理,将另一个半部分归并,得到[1,2,5,7,9]
  3. 合并:最终将[3,4,6,8][1,2,5,7,9]进行合并,得到[1,2,3,4,5,6,7,8,9]

示例二

假设我们有一个长度为1000的随机数组,需要进行排序并统计时间复杂度。

#include <iostream>
#include <vector>

using namespace std;

void merge(vector<int>& nums, int start, int mid, int end) {
    int left = start, right = mid + 1;
    vector<int> temp;
    while (left <= mid && right <= end) {
        if (nums[left] <= nums[right])
            temp.push_back(nums[left++]);
        else
            temp.push_back(nums[right++]);
    }
    while (left <= mid)
        temp.push_back(nums[left++]);
    while (right <= end)
        temp.push_back(nums[right++]);
    for (int i = 0; i < temp.size(); ++i) 
        nums[start + i] = temp[i];
}

void mergeSort(vector<int>& nums, int start, int end) {
    if (start >= end) return;
    int mid = (start + end) / 2;
    mergeSort(nums, start, mid);
    mergeSort(nums, mid + 1, end);
    merge(nums, start, mid, end);
}

int main() {
    vector<int> nums;
    for (int i = 0; i < 1000; ++i)
        nums.push_back(rand() % 1000);
    mergeSort(nums, 0, nums.size() - 1);
    for (int num : nums)
        cout << num << " ";
    return 0;
}

在示例二中,我们生成了一个长度为1000的随机数组,使用归并排序进行排序,并统计时间复杂度。通过测试数据发现,对于长度为1000的序列,归并排序的时间复杂度在0.5ms左右。

总结

本文详细讲解了C++归并排序算法的基本原理、代码实现和示例。归并排序划分自序列、递归和合并操作使得它的时间复杂度为O(nlogn),并且稳定性在实际应用中得到了广泛的应用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c++归并排序详解 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • JS中数组随机排序实现方法(原地算法sort/shuffle算法)

    JS中实现数组随机排序有两种常见方法:原地随机排序算法和使用shuffle算法。 原地随机排序算法 原地随机排序算法(in-place shuffle algorithm)是将数组中元素随机地乱序,同时保持每个元素之间的相对位置不变。算法的时间复杂度是O(n),空间复杂度是O(1),因为所有的操作都是在原数组上进行。 实现步骤 获取数组长度 从数组的最后一个…

    算法与数据结构 2023年5月19日
    00
  • JS深入学习之数组对象排序操作示例

    《JS深入学习之数组对象排序操作示例》是一篇介绍JavaScript数组排序相关操作的文章,主要包含以下内容: 1. 数组对象排序 1.1 sort()方法 sort()方法是JavaScript中的一个数组排序方法,可以用于对数组的元素进行排序。sort()方法可以接收一个可选的排序函数作为参数,通过这个函数,我们可以实现自定义的排序规则。 语法为:arr…

    算法与数据结构 2023年5月19日
    00
  • javascript中可能用得到的全部的排序算法

    Javascript中可能用得到的全部排序算法 在JavaScript中,排序算法是非常常见和重要的。因为在编写程序时,我们经常需要对数组、集合等数据结构进行排序操作。接下来,我将按照常用的一些排序算法逐一介绍。 冒泡排序(Bubble Sort) 冒泡排序是一种简单的交换排序算法。它通过相邻两个元素的比较和交换来排序。每一轮比较都会将最大的元素沉到最底部。…

    算法与数据结构 2023年5月19日
    00
  • JS中的算法与数据结构之列表(List)实例详解

    首先,列表(List)是一种非常常见且重要的数据结构,用于存储一组顺序排列的数据。在JavaScript中,可以通过数组来实现列表。 具体来说,我们可能会涉及到一些常用的列表操作,例如: 在数组尾部添加一个元素 在数组特定位置插入一个元素 从数组中删除指定元素 获取数组中指定位置的元素 下面,我们将结合代码示例,一一介绍这些操作: 在数组尾部添加一个元素 在…

    算法与数据结构 2023年5月19日
    00
  • C语言下快速排序(挖坑法)详解

    C语言下快速排序(挖坑法)详解 什么是快速排序 快速排序是将一个待排序的序列分成两部分,其中一部分的所有元素都比另一部分的所有元素小,然后再对这两部分分别进行排序,递归执行该操作直到将整个序列排好为止。快速排序使用了分治思想。由于在每一次的递归过程中,都将待排序的序列分成两部分,因此处理的数据量不断减少,使得算法的效率比较高。 快速排序的实现 挖坑法 挖坑法…

    算法与数据结构 2023年5月19日
    00
  • C C++算法题解LeetCode1408数组中的字符串匹配

    C C++算法题解LeetCode1408数组中的字符串匹配 问题描述 给定字符串数组 words,在其中找到两个不同的单词,使得它们的长度之和最长。可以假设 words 中至少存在两个单词。 返回两个单词长度之和的最大值。 解题思路 方法一:暴力枚举 我们可以将字符串数组中的字符串两两组合,计算它们的长度之和并更新最大值,最后返回最大值即可。 时间复杂度:…

    算法与数据结构 2023年5月19日
    00
  • 数组Array的排序sort方法

    下面是关于JavaScript中数组排序sort()方法的详细攻略。 标准语法 array.sort(compareFunction) 参数 compareFunction是可选的,是用来指定按照什么顺序进行排序的,具体取决于具体实现。 如果省略,sort() 方法按照每个字符的 Unicode 代码点进行排序,因此 “10” 在排列时会在 “2” 之前,此…

    算法与数据结构 2023年5月19日
    00
  • java简单冒泡排序实例解析

    Java简单冒泡排序是一种常见的排序算法,它通过不断比较相邻元素的大小,并交换相邻元素的位置,从而将最大(最小)的元素逐渐交换到序列的顶端(底端),实现排序操作。在本篇文章中,我们将详细讲解如何使用Java实现简单的冒泡排序算法。 算法实现思路 定义一个整型数组,包含待排序的元素 使用for循环嵌套,通过不断比较相邻的元素大小,将最大(最小)元素逐渐移到数组…

    算法与数据结构 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部