Merge sort
来源:互联网 发布:java开发物流管理系统 编辑:程序博客网 时间:2024/05/20 04:15
Backdrop
听萌神说归并排序有两种,意识到自己当年没有好好学。于是就上维基百科补了下课。
https://en.wikipedia.org/wiki/Merge_sort
Main
虽然说是两种,但是都是归并排序。也就是说思路是不变的。总共分两步:
- Divide the unsorted list into n sublists, each containing 1 element (a list of 1 element is considered sorted).
- Repeatedly merge sublists to produce new sorted sublists until there is only 1 sublist remaining. This will be the sorted list.
Bottom-up implementation
C-like Pseudocode
/* array A[] has the items to sort; array B[] is a work array */void BottomUpMergeSort(A[], B[], n){ /* Each 1-element run in A is already "sorted". */ /* Make successively longer sorted runs of length 2, 4, 8, 16... until whole array is sorted. */ for (width = 1; width < n; width = 2 * width) { /* Array A is full of runs of length width. */ for (i = 0; i < n; i = i + 2 * width) { /* Merge two runs: A[i:i+width-1] and A[i+width:i+2*width-1] to B[] */ /* or copy A[i:n-1] to B[] ( if(i+width >= n) ) */ BottomUpMerge(A, i, min(i+width, n), min(i+2*width, n), B); } /* Now work array B is full of runs of length 2*width. */ /* Copy array B to array A for next iteration. */ /* A more efficient implementation would swap the roles of A and B */ CopyArray(B, A, n); /* Now array A is full of runs of length 2*width. */ }}void BottomUpMerge(A[], iLeft, iRight, iEnd, B[]){ i0 = iLeft; i1 = iRight; j; /* While there are elements in the left or right runs */ for (j = iLeft; j < iEnd; j++) { /* If left run head exists and is <= existing right run head */ if (i0 < iRight && (i1 >= iEnd || A[i0] <= A[i1])) { B[j] = A[i0]; i0 = i0 + 1; } else { B[j] = A[i1]; i1 = i1 + 1; } }}void CopyArray(B[], A[], n){ for(i = 0; i < n; i++) A[i] = B[i];}
Something
这个格式居然是 GNU,感觉好怀念……
其实关键在 mergesort 的描述居然是跟平时学习的不一样的。如果是根据上述的描述,代码自然就是 Bottom-up 形式的。
那么……第二种当然就是……
Top-down implementation
C-like Pseudocode
/* array A[] has the items to sort; array B[] is a work array */TopDownMergeSort(A[], B[], n){ TopDownSplitMerge(A, 0, n, B);}// iBegin is inclusive; iEnd is exclusive (A[iEnd] is not in the set)TopDownSplitMerge(A[], iBegin, iEnd, B[]){ if(iEnd - iBegin < 2) // if run size == 1 return; // consider it sorted // recursively split runs into two halves until run size == 1, // then merge them and return back up the call chain iMiddle = (iEnd + iBegin) / 2; // iMiddle = mid point TopDownSplitMerge(A, iBegin, iMiddle, B); // split / merge left half TopDownSplitMerge(A, iMiddle, iEnd, B); // split / merge right half TopDownMerge(A, iBegin, iMiddle, iEnd, B); // merge the two half runs CopyArray(B, iBegin, iEnd, A); // copy the merged runs back to A}// left half is A[iBegin :iMiddle-1]// right half is A[iMiddle:iEnd-1 ]TopDownMerge(A[], iBegin, iMiddle, iEnd, B[]){ i0 = iBegin, i1 = iMiddle; // While there are elements in the left or right runs for (j = iBegin; j < iEnd; j++) { // If left run head exists and is <= existing right run head. if (i0 < iMiddle && (i1 >= iEnd || A[i0] <= A[i1])) { B[j] = A[i0]; i0 = i0 + 1; } else { B[j] = A[i1]; i1 = i1 + 1; } } }CopyArray(B[], iBegin, iEnd, A[]){ for(k = iBegin; k < iEnd; k++) A[k] = B[k];}
Top-down implementation using lists
Pseudocode for top down merge sort algorithm which recursively divides the input list into smaller sublists until the sublists are trivially sorted, and then merges the sublists while returning up the call chain.
function merge_sort(list m) // Base case. A list of zero or one elements is sorted, by definition. if length(m) <= 1 return m // Recursive case. First, *divide* the list into equal-sized sublists. var list left, right var integer middle = length(m) / 2 for each x in m before middle add x to left for each x in m after or equal middle add x to right // Recursively sort both sublists left = merge_sort(left) right = merge_sort(right) // Then merge the now-sorted sublists. return merge(left, right)function merge(left, right) var list result while notempty(left) and notempty(right) if first(left) <= first(right) append first(left) to result left = rest(left) else append first(right) to result right = rest(right) // either left or right may have elements left while notempty(left) append first(left) to result left = rest(left) while notempty(right) append first(right) to result right = rest(right) return result
Natural merge sort
这个是 mergesort 的 Bottom-up 形式经过一点改动得到的。
Bottom-up 形式是一开始划分成 n 个 长度为 1 的子序列,然而 Natural merge sort 则充分利用了原来序列的连续递增的部分,把连续递增的部分划分为一个子序列。
下面给出一个例子:
Start : 3--4--2--1--7--5--8--9--0--6Select runs : 3--4 2 1--7 5--8--9 0--6Merge : 2--3--4 1--5--7--8--9 0--6Merge : 1--2--3--4--5--7--8--9 0--6Merge : 0--1--2--3--4--5--6--7--8--9
如果序列是单调递减的,那么 Natural merge sort 也就没有额外的优势。
0 0
- Merge Sort
- Merge sort
- merge sort
- merge sort
- merge sort
- Merge Sort
- merge sort
- Merge Sort
- Merge Sort
- merge sort
- Merge Sort
- Merge sort
- Merge-sort
- Merge Sort
- Merge sort
- Merge Sort
- Merge-Sort
- merge sort
- Codeforces Bubble Cup 8 - Finals [Online Mirror] 解题报告
- 打开Dreamweaver出现配置错误的解决方法
- JVM运行时数据区域
- sting的方法总结
- 控制GridView中的行高
- Merge sort
- Android五大存储---外部存储(SD卡)
- SQL-----sql
- nginx集群的配置
- 如何把vivado中实时截取的debug信号保存下来
- 压缩文件:
- iOS数据持久化
- 09-07 Fragment(碎片续)、数据存储(Preference)
- Binary Search 二分查找