归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
归并操作的工作原理如下:
申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
设定两个指针,最初位置分别为两个已经排序序列的起始位置
比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针达到序列尾
将另一序列剩下的所有元素直接复制到合并序列尾
/// <summary> /// 归并排序 /// </summary> /// <param name="intArr"></param> static void MergeSort(int[] intArr) { //统计比较和交换次数 int numberOfLoop = 0; int numberOfSwap = 0; int[] tempArr = new int[intArr.Length]; MergeAdjust(tempArr,ref intArr, 0, intArr.Length - 1, ref numberOfLoop, ref numberOfSwap); DisplaySortResult(numberOfLoop, numberOfSwap, intArr); } /// <summary> /// 递归调用归并 /// </summary> /// <param name="tempArr"></param> /// <param name="intArr"></param> /// <param name="left"></param> /// <param name="right"></param> /// <param name="numberOfLoop"></param> /// <param name="numberOfSwap"></param> private static void MergeAdjust(int[] tempArr, ref int[] intArr, int left, int right, ref int numberOfLoop, ref int numberOfSwap) { if (left != right) { int middle = (left + right) / 2; //递归,继续细分数组,最后比较相邻的两个元素 MergeAdjust(tempArr, ref intArr, left, middle, ref numberOfLoop, ref numberOfSwap); MergeAdjust(tempArr, ref intArr, middle + 1, right, ref numberOfLoop, ref numberOfSwap); //归并 Merge(tempArr, ref intArr, left, middle + 1, right, ref numberOfLoop, ref numberOfSwap); } } /// <summary> /// 归并操作 /// </summary> /// <param name="tempArr"></param> /// <param name="intArr"></param> /// <param name="left"></param> /// <param name="rl"></param> /// <param name="right"></param> /// <param name="numberOfLoop"></param> /// <param name="numberOfSwap"></param> private static void Merge(int[] tempArr, ref int[] intArr, int left, int rl, int right, ref int numberOfLoop, ref int numberOfSwap) { int ll = left;//数组一左侧 int lr = rl - 1;//数组一右侧 int i = 0; while (ll <= lr && rl <= right) { numberOfLoop++; numberOfSwap++; //两个数组比较,将小的先插入 if (intArr[ll] < intArr[rl]) { tempArr[i] = intArr[ll]; ll++; } else { tempArr[i] = intArr[rl]; rl++; } i++; } //上边对数组进行归并后,可能有一个数组会有剩余的元素 //拷贝数组一剩余的部分到临时数组 while (ll <= lr) { numberOfLoop++; numberOfSwap++; tempArr[i] = intArr[ll]; ll++; i++; } //拷贝数组二剩余的部分到临时数组 while (rl <= right) { numberOfLoop++; numberOfSwap++; tempArr[i] = intArr[rl]; rl++; i++; } //将有序数据更新到数组中 for (int j = 0; j <= i-1; j++) { numberOfSwap++; intArr[left + j] = tempArr[j]; } }
运行效率和快速排序、堆排序差不多:
发表评论
相关文章
国内AI资源汇总,AI聊天、AI绘画、AI写作、AI视频、AI设计、AI编程、AI音乐等,国内顺畅访问,无需科学上网。
扫码或点击进入:萤火AI大全
文章分类
最新评论