经典排序算法(8)——归并排序算法详解

归并排序(Merge sort),是创建在归并操作上的一种有效的排序算法,效率为O(nlog n)。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。

一、算法基本思想

(1)基本思想

归并排序的基本思想就是:把待排序序列分为若干个子序列,每个子序列是有序的,然后再把有序子序列合并为整体有序序列。经常被使用的是二路归并算法,即将两个已经排序的序列合并成一个序列的操作。

(2)运行过程

归并排序算法的运行过程如下:

1、申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;

2、设定两个指针,最初位置分别为两个已经排序序列的起始位置;

3、比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;

4、重复步骤3直到某一指针达到序列尾;

5、将另一序列剩下的所有元素直接复制到合并序列尾。

(3)示例

《经典排序算法(8)——归并排序算法详解》


二、算法实现(核心代码)

C++实现:

template<typename T> //整数或浮点数皆可使用
void merge_sort(T arr[], int len) {
	T* a = arr;
	T* b = new T[len];
	for (int seg = 1; seg < len; seg += seg) {
		for (int start = 0; start < len; start += seg + seg) {
			int low = start, mid = min(start + seg, len), high = min(start + seg + seg, len);
			int k = low;
			int start1 = low, end1 = mid;
			int start2 = mid, end2 = high;
			while (start1 < end1 && start2 < end2)
				b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
			while (start1 < end1)
				b[k++] = a[start1++];
			while (start2 < end2)
				b[k++] = a[start2++];
		}
		T* temp = a;
		a = b;
		b = temp;
	}
	if (a != arr) {
		for (int i = 0; i < len; i++)
			b[i] = a[i];
		b = a;
	}
	delete[] b;
}

Java实现:

public void merge_sort(int[] arr) {
    int len = arr.length;
    int[] result = new int[len];
    int block, start;
		
    for(block = 1; block < len ; block *= 2) {
        for(start = 0; start <len; start += 2 * block) {
            int low = start;
            int mid = (start + block) < len ? (start + block) : len;
            int high = (start + 2 * block) < len ? (start + 2 * block) : len;
            //两个块的起始下标及结束下标
            int start1 = low, end1 = mid;
            int start2 = mid, end2 = high;
            //开始对两个block进行归并排序
            while (start1 < end1 && start2 < end2) {
	        result[low++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];
            }
            while(start1 < end1) {
	        result[low++] = arr[start1++];
            }
            while(start2 < end2) {
	        result[low++] = arr[start2++];
            }
        }
	int[] temp = arr;
	arr = result;
	result = temp;
    }
    result = arr;       
}

三、性能(算法时间、空间复杂度、稳定性)分析

归并排序的时间复杂度为O(nlogn)空间复杂度为O(n);是稳定的排序算法

归并排序速度仅次于快速排序,为稳定排序算法。一般用于对总体无序,但是各子项相对有序的数列效果比较好。

    原文作者:常用算法
    原文地址: https://blog.csdn.net/guoweimelon/article/details/50904237
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞