1.概述
原理:把原始数组分成若干子数组,对每一个子数组进行排序,继续把子数组与子数组合并,合并后仍然有序,直到全部合并完,形成有序的数组,因此空间复杂度为O(n)。
归并操作的过程如下:
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
- 重复步骤3直到某一指针达到序列尾
- 将另一序列剩下的所有元素直接复制到合并序列尾
理解:递归便是深度遍历(如下由左至右进行遍历),假设有这样的一列数组{9,8,7,6,5,4,3,2,1}进行划分的顺序如下:
{9,8,7,6,5,4,3,2,1} --> {9,8,7,6,5},{4,3,2,1}
{9,8,7,6,5} --> {9,8,7},{6,5}
{9,8,7} --> {9,8},{7}
{9,8} --> {9},{8}
{6,5} -->{6},{5}
{4,3,2,1} --> {4,3},{2,1}
{4,3} -->{4},{3}
{2,1} -->{2},{1}
当深度划分到左右数组都只剩1个元素的时候,进行上述逆序的合并:
{9},{8} --> {8,9} 然后和 {7} --> {7,8,9}
{6},{5} --> {5,6} 然后 {7,8,9}和{5,6} --> {5,6,7,8,9}
{2},{1} --> {1,2}
{4},{3} --> {3,4} 然后 {1,2}和 {3,4} --> {1,2,3,4}
最终{5,6,7,8,9}和{1,2,3,4} --> {1,2,3,4,5,6,7,8,9}
2.示例
//归并排序 public static int[] MergeSort(int[] nums) { if (nums.Length < 2) return nums; int mid = nums.Length / 2; int[] left = new int[mid]; int[] right = new int[nums.Length - mid]; for (int i = 0; i < mid; i++) { left[i] = nums[i]; } for (int j = mid; j < nums.Length; j++) { right[j - mid] = nums[j]; } left = MergeSort(left); right = MergeSort(right); return merge(left, right); } private static int[] merge(int[] left, int[] right) { int[] temp = new int[left.Length + right.Length]; int tempIndex = 0, lIndex = 0, rIndex = 0; while (lIndex < left.Length && rIndex < right.Length) { if (left[lIndex] <= right[rIndex]) { temp[tempIndex++] = left[lIndex++]; } else { temp[tempIndex++] = right[rIndex++]; } } for (int i = lIndex; i < left.Length; i++) { temp[tempIndex++] = left[i]; } for (int i = rIndex; i < right.Length; i++) { temp[tempIndex++] = right[i]; } return temp; } // int[] list = new[] { 9, 8, 7, 6, 5, 4, 3, 2, 1 }; // var sort = Sorter.MergeSort(list);
参考:http://www.cnblogs.com/mingmingruyuedlut/archive/2011/08/18/2144984.html