归并排序是一种基于分治思想的经典排序算法。它将待排序的数组分成两个部分,然后递归地对这两个部分进行排序,最后再将排序好的两个部分归并成一个有序的数组。
具体实现过程如下:
1. 将待排序数组不断二分,直到只剩下一个元素,此时该元素就是有序的。
2. 将相邻的两个有序数组合并成一个有序数组。合并时,对于两个数组中首位元素进行比较,将较小的元素放入新数组中,直到一个数组全部放入新数组中,最后将另一个数组直接拼接到新数组的后面。
3. 重复步骤2,直到所有的数组合并成一个有序数组。
时间复杂度为O(nlogn),是稳定的排序算法,但空间复杂度为O(n),需要额外的存储空间。
python实现:
- def merge_sort(arr):
- if len(arr) <= 1:
- return arr
-
- mid = len(arr) // 2
- left = merge_sort(arr[:mid])
- right = merge_sort(arr[mid:])
-
- return merge(left, right)
-
- def merge(left, right):
- result = []
- left_index = 0
- right_index = 0
-
- while left_index < len(left) and right_index < len(right):
- if left[left_index] <= right[right_index]:
- result.append(left[left_index])
- left_index += 1
- else:
- result.append(right[right_index])
- right_index += 1
-
- result += left[left_index:]
- result += right[right_index:]
-
- return result
C++实现:
- #include
- #include
-
- using namespace std;
-
- // 归并两个有序数组
- void merge(vector<int>& nums, int left, int mid, int right) {
- int i = left, j = mid + 1, k = 0;
- vector<int> temp(right - left + 1);
- while (i <= mid && j <= right) {
- if (nums[i] < nums[j])
- temp[k++] = nums[i++];
- else
- temp[k++] = nums[j++];
- }
- while (i <= mid)
- temp[k++] = nums[i++];
- while (j <= right)
- temp[k++] = nums[j++];
- for (int p = 0; p < k; ++p)
- nums[left + p] = temp[p];
- }
-
- // 归并排序
- void merge_sort(vector<int>& nums, int left, int right) {
- if (left < right) {
- int mid = left + (right - left) / 2;
- merge_sort(nums, left, mid); // 排序左边子数组
- merge_sort(nums, mid + 1, right); // 排序右边子数组
- merge(nums, left, mid, right); // 合并有序子数组
- }
- }
-
- int main() {
- vector<int> nums = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5}; // 待排序数组
- merge_sort(nums, 0, nums.size() - 1); // 归并排序
- for (int i = 0; i < nums.size(); ++i) // 输出排序结果
- cout << nums[i] << " ";
- cout << endl;
- return 0;
- }
Java实现:
- public class MergeSort {
-
- 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) {
- int[] temp = new int[right - left + 1]; // 临时数组,存放合并后的序列
- int i = left, j = mid + 1, k = 0;
-
- while (i <= mid && j <= right) { // 将左右两个有序序列合并
- if (arr[i] <= arr[j]) {
- temp[k++] = arr[i++];
- } else {
- temp[k++] = arr[j++];
- }
- }
-
- while (i <= mid) { // 将左边剩余元素填充进temp中
- temp[k++] = arr[i++];
- }
-
- while (j <= right) { // 将右边剩余元素填充进temp中
- temp[k++] = arr[j++];
- }
-
- for (int p = 0; p < temp.length; p++) { // 将temp中的元素全部拷贝到原数组中
- arr[left + p] = temp[p];
- }
- }
-
- }