归并排序(MergeSort)
归并排序的核心思想是“分治”(分的过程中将问题分解成小问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
它是一种稳定的排序, 时间复杂度为O(nlogn)
例如要将【8,4,5,7,1,3,6,2】 排序,步骤如下图
分的过程中调用递归函数,将其拆分成许多小的部分,直到只剩一个元素停止拆分,开始治的过程
治的时候需要定义一个temp数组,将左右两部分合并的内容存储在里面
使用两个指针,分别指向左边第一个位置和右边第一个位置,比较它们在数组中的大小 值小的下标往后移一位,值大的不变
下面是【4,5,7,8】和【1,2,3,6】合并的过程
代码如下:
static void Main(string[] args) { int[] arr = new int[] { 2, 5, 7, 3, 8, 4, 9, 1 }; MergeSort(arr, 0, arr.Length - 1); } private static void MergeSort(int[] arr, int left, int right) { //left == right 说明只有一个元素 返回 if (left == right) return; int mid = (left + right) / 2; MergeSort(arr, left, mid); MergeSort(arr, mid + 1, right); Merge(arr, left, mid, right); } private static void Merge(int[] arr, int left, int mid, int right) { int[] temp = new int[right - left + 1]; //lStart:左边第一个元素 rStart:右边第一个元素 int lStart = left, rStart = mid + 1; //help数组下标 int index = 0; while(lStart<=mid && rStart <= right) { //两个下标都没有越界,将help数组中填入他们中较小的数 并且下标右移 temp[index++] = arr[lStart] < arr[rStart] ? arr[lStart++] : arr[rStart++]; } //如果左边有剩下的,将他直接复制到help数组里面 while (lStart <= mid) { temp[index++] = arr[lStart++]; } //如果右边有剩下的,将他直接复制到help数组里面(和上面的while只会执行一个) while (rStart <= right) { temp[index++] = arr[rStart++]; } //将help数组的内容复制到arr的对应位置 Array.Copy(temp, 0, arr, left, index); }
注:图片来源
作者: dreamcatcher-cx