浅说归并排序
今天又习得一排序算法 :归并排序 特与大家分享下 一起消化它!
定义:
顾名思义 归并排序 即是先递归获取排序后的分组 然后将分组合并 最后排序完成
暴力解释:
首先假如我们有一个数组为 [1] 是的 这个数组就只有一个数字 有的人就问了 :你这不吭麽? 一个元素你丫还来排序? 好吧,所以说当数组中的元素
个数为1时 则递归结束 这个组的排序完成! 而且它并不需要合并
那么当数组是 [2,1]的时候呢? 这个时候 我们就要将这个数组分组 一分为二 分别为 数组arrX=[2] 数组arrY=[1] 我们再分别来看这两个数组
首先看arrX 好你个小子 元素总数都为1了 你丫又闹排序?因此 如前面所言 当一个组的元素个数为1时 这个组的排序完成 递归结束 对于arrY亦然
现在两个组排序完成了 已经变成了两个有序的数组 接下来就要将两个数组合并了 首先我们先定义一个 arr[]数组 它的长度是arrX和arrY的长度之和
然后我们分别来看arrX[0] 和arrY[0] 看哪个元素小(此处为升序排序) 我就把这个元素丢到arr数组中
这里arrY[0]<arrX[0] 因此arr[0]=arrY[0]; 这时arrY中已经没有元素了 而arrX数组是已经排序完成的 那么我们只需按顺序再把arrX中的元素依次放入arr数组中
即:arr[1]=arrX[0]; 这样 一个完全排序好的arr数组就诞生了!
因此所谓的归并排序 其实就是先将一个数组递归拆分成N个小数组 每一个小数组的元素个数为1 然后11合并为2 22合并为4 以此类推 一直合并到原来数组长度
在两个小数组合并为一个大数组的过程中 两个小数组按下标顺序一一比较 当某一个小数组的元素个数为0时 则另外一个小数组只需将余下的元素拼接到新数组末尾即
可 最后排序完成!
附上代码 不成敬意:(数组使用微软封装好的List<int> 更加浅显易懂)
递归拆分:
1 private static List<int> DivideSort(List<int> arr) 2 { 3 //如果只有一位 那当然就不用排序了 直接返回 递归结束 4 if (arr.Count <= 1) 5 { 6 return arr; 7 } 8 //一分为二 拆分数组 9 int middle = arr.Count / 2; 10 List<int> left = new List<int>(); 11 List<int> right = new List<int>(); 12 for (int i = 0; i < middle; i++) 13 { 14 left.Add(arr[i]); 15 } 16 for (int j = middle; j < arr.Count; j++) 17 { 18 right.Add(arr[j]); 19 } 20 left = DivideSort(left); 21 right = DivideSort(right); 22 //进行合并 23 return MergeList(left, right); 24 }
合并排序:
1 private static List<int> MergeList(List<int> left, List<int> right) 2 { 3 //临时大数组 4 List<int> newList = new List<int>(); 5 //两个小数组都有元素 那当然要进行比较 6 while (left.Count > 0 && right.Count > 0) 7 { 8 if (left[0] <= right[0]) 9 { 10 newList.Add(left[0]); 11 left.RemoveAt(0); 12 } 13 else 14 { 15 newList.Add(right[0]); 16 right.RemoveAt(0); 17 } 18 } 19 //总算有一个小数组败下阵来 因此另外一个小数组的剩余元素 只需按顺序添加到大数组即可 20 if (left.Count > 0) 21 { 22 for (int i = 0; i < left.Count; i++) 23 { 24 newList.Add(left[i]); 25 } 26 } 27 //同上 28 else if (right.Count > 0) 29 { 30 for (int i = 0; i < right.Count; i++) 31 { 32 newList.Add(right[i]); 33 } 34 } 35 return newList; 36 }
园友,贫道看你骨骼惊奇,仪表非凡,定非池中之物,将来必成大事。这样吧,右下角有一个推荐,速度秒了它,我就与你一起拯救世界,如何?