掌握C++归并排序算法的代码实现

需积分: 10 1 下载量 7 浏览量 更新于2024-11-04 收藏 1KB ZIP 举报
资源摘要信息:"归并排序是一种有效的排序算法,它采用分治法(Divide and Conquer)的一个典型应用。它将一个数组分成两半,对每一半分别进行排序,然后将结果合并成一个有序数组。归并排序的时间复杂度为O(n log n),适用于各种类型的输入数据,且其在最坏、平均和最好的情况下都保持稳定的性能。归并排序不是原地排序算法,需要O(n)的额外空间,这是它的主要缺点。尽管如此,归并排序在处理大量数据时仍然表现出色。 cpp代码实现归并排序,主要由以下几个步骤组成: 1. 分割:递归地将当前区间一分为二,即求中点 mid = (low + high) / 2; 2. 合并:将已排序的两个子序列合并成一个最终的排序序列。 以下是一个简单的C++代码示例,用于演示归并排序的基本实现: ```cpp #include <iostream> #include <vector> using namespace std; void merge(vector<int>& arr, int left, int mid, int right) { int n1 = mid - left + 1; int n2 = right - mid; vector<int> L(n1), R(n2); // 创建临时数组 // 复制数据到临时数组 L[] 和 R[] for (int i = 0; i < n1; i++) L[i] = arr[left + i]; for (int j = 0; j < n2; j++) R[j] = arr[mid + 1 + j]; // 合并临时数组回 arr[left..right] int i = 0, j = 0, k = left; 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++; } } // 主函数,对 arr[0..n-1] 进行归并排序 void mergeSort(vector<int>& arr, int left, int right) { if (left < right) { // 找到中间点 int mid = left + (right - left) / 2; // 分别对左右两半进行排序 mergeSort(arr, left, mid); mergeSort(arr, mid + 1, right); // 合并两半 merge(arr, left, mid, right); } } // 打印数组 void printArray(const vector<int>& arr) { for (int num : arr) { cout << num << " "; } cout << endl; } // 主函数 int main() { vector<int> arr = {12, 11, 13, 5, 6, 7}; cout << "给定的数组是:\n"; printArray(arr); mergeSort(arr, 0, arr.size() - 1); cout << "\n排序后的数组是:\n"; printArray(arr); return 0; } ``` 该代码包含了一个主要的排序函数`mergeSort`和一个辅助的合并函数`merge`。`mergeSort`函数将数组分成更小的部分,直到每个子数组只有一个元素,然后开始递归合并这些数组。`merge`函数则负责将两个已排序的子数组合并成一个有序的数组。代码中的`main`函数用于演示如何使用这些函数对一个整数数组进行排序。 在阅读代码的同时,应当注意到以下几点: - 归并排序是递归实现的,递归调用在数组被分为足够小的部分以至于可以逐个元素进行排序时停止。 - 归并排序在合并阶段要求额外的存储空间来临时存储子数组,这是因为归并排序不是原地排序。 - 归并排序对于链表结构而言,可以实现为原地排序,因为链表可以很容易地通过指针来重新链接,而不需要像数组那样移动元素。 编写归并排序代码是算法和数据结构课程中重要的练习之一,它有助于加深对分治法策略的理解。"