归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
super T> c) { T[] aux = (T[])a.clone(); if (c==null) mergeSort(aux, a, 0, a.length, 0); else mergeSort (aux, a, 0, a.length, 0, c); } 克隆一个数组,如果比较器为空,mergeSort(aux, a, 0, a.length, 0);如果比较器不为空,mergeSort private static void mergeSort(Object[] src, Object[] dest, int low, int high, int off, (dest, src, low, mid, -off, c); mergeSort(dest, src, mid, high, -off, c); // If list is already sorted (dest, src, low, mid, -off, c);// 排序左边 mergeSort(dest, src, mid, high, -off, c);// 排序右边 这里开始递归排序
我们就可以进行归并, 取小的数据进行依次排列, 那么我们就需要一个临时的数组进行存放, 首先动态申请块与数组空间大小相同的空间, 然后进行内层函数的递归调用, 不能直接调用外层函数, 因为会重复申请空间. void MergeSort * tmp = (int*)malloc(sizeof(int) * n); if (tmp == NULL) { perror("malloc fail"); return; } _MergeSort 这也可见学习算法是具有连贯性和螺旋式上升的一个过程, 接着我们需要拷贝临时数组的数据到原数组中, 每次归并一小段区间就要拷贝一次, 以免有不必要的麻烦, 到此我们的归并排序已经完成.是不是比较简单. void _MergeSort int* tmp, int begin, int end) { if (begin >= end) { return; } int mid = (begin + end) / 2; _MergeSort (a, tmp, begin, mid); _MergeSort(a, tmp, mid + 1, end); int begin1 = begin, end1 = mid; int begin2
继续对左右两条链表进行划分 ListNode R = divList(Rhead); return mergeList(L,R); //返回merge后的链表的表头 } ListNode mergeSort before merge sort: " << endl; intList.PrintList(); //排序前链表打印 intList.SetHeadNode(mergeSort
算法原理 归并排序我们应该不陌生, 这里我们只是复习归并排序的算法原理 3.代码 public int[] sortArray(int[] nums) { mergeSort( nums,0,nums.length-1); return nums; } public void mergeSort(int[] nums, int s, int e) (nums,s,mid); // 递归右区间 mergeSort(nums,mid + 1,e); // 递归完成后, 给两个数组排序(数组并不是真实数组 (nums, 0,nums.length - 1); return ret; } public void mergeSort(int[] nums, int start, (nums, start, mid); // 递归右面[mid+1,e] mergeSort(nums, mid + 1, end); // 递归结束,
二、实现归并排序 MergeSort函数 由于需要不断的进行递归式的分解数组,所以在原数组上操作是不方便的,于是我们在MergeSort函数中malloc出一个空间用于相关操作。 temp)return; _MergeSort(a, 0, n - 1, temp); free(temp); temp = NULL; } 既然MergeSort函数中存在申请空间的行为, _MergeSort函数 _MergeSort函数用于进行递归分数组和子数组合并。 _MergeSort(a, left, div, t); _MergeSort(a, div+ 1, right, t); 所以函数至少需要四个形参:传原数组;传分数组的的左端;传分数组的的右端;在MergeSort temp)return; _MergeSort(a, 0, a_size- 1, temp); free(temp); temp = NULL; } void _MergeSort(int
描述合并排序的伪代码如下: PROCEDURE function mergeSort FOR each element of the master list indexed by i i <= 1 ) return a var left = a[0] to a[i/2] var right = a[i/2+1] to a[i] left = mergeSort function mergeSort WHILE length(left) > 0 and length(right) > 0 if first(left) ≤ first(right 这导致我们需要两个PHP函数,其中第一个函数(mergeSort)涉及递归。 <? ($left); $right = mergeSort($right); return merge($left, $right);} function merge($left, $right
(nums, 0, sz - 1); return nums; } void MergeSort(vector<int>& arr, int l, int r) { if (l >= r) return; int mid = (l + r) >> 1; MergeSort(arr, l, mid); MergeSort(arr, mid + 1, r); int b1 = l, b2 = mid + 1, i = l; while (b1 <= mid && b2 < (record, 0, sz - 1); } int MergeSort(vector<int>& arr, int l, int r) { if (l >= r if (l >= r) return; int mid = (l + r) >> 1; MergeSort(arr, l, mid); MergeSort
(vector<T>& A, int l, int r) { if (l >= r) return; int mid = l + (r - l) / 2; _mergesort (A, l, mid); _mergesort(A, mid+1, r); merge(A, l, mid, r); } template <typename T> void mergesort (vector<T>& A) { _mergesort(A, 0, A.size()-1); } 快速排序原理 核心思想:选取一个基准元素 pivot,比 pivot 小的放到左边,比 pivot ", arr1, mergesort<int>); sort_helper::testsort<int>("quicksort", arr2, quicksort<int>); // ", arr5, mergesort<int>); sort_helper::testsort<int>("quicksort", arr6, quicksort<int>); } 运行结果如下
(nums,0,n-1); return nums; } void MergeSort(vector<int>& nums,int left,int right) (nums,left,mid); MergeSort(nums,mid+1,right); //3.进行归并 int i=left;//帮助还原 ) return 0; int mid=(right+left)>>1; int ret=0; ret+=MergeSort(nums,left,mid) ) return 0; int mid=(right+left)>>1; int ret=0; ret+=MergeSort(nums,left,mid) ) return 0; int mid=(right+left)>>1; int ret=0; ret+=MergeSort(nums,left,mid)
tem = new int[right-left+1] 而不是 new int[nums.length]; 优化点:tem数组只是一个中间商,不用每次递归都new一个,给他提出来作为全局变量,首次进mergeSort ) { //归并排序 //传入的参数:数组,左边界,右边界 int left = 0 , right = nums.length-1; mergeSort (nums,left,right);//对整个区间进行排序 return nums; } public void mergeSort(int[] nums , int left (nums,left,mid); mergeSort(nums,mid+1,right); //4:合并排序好的两个区间 int cur1 = left (record,0,n-1); } public int mergeSort(int[] nums , int left , int right){ if(left >
递归调用树如下所示: mergeSort(0, 15) ├── mergeSort(0, 7) │ ├── mergeSort(0, 3) │ │ ├── mergeSort(0, 1) │ │ │ └── mergeSort(0, 0) │ │ └── mergeSort(2, 3) │ │ └── mergeSort(2, 2) │ └── mergeSort └── mergeSort(6, 6) └── mergeSort(8, 15) ├── mergeSort(8, 11) │ ├── mergeSort(8, 9) │ │ └── mergeSort(8, 8) │ └── mergeSort(10, 11) │ └── mergeSort(10, 10) └── mergeSort (12, 15) ├── mergeSort(12, 13) │ └── mergeSort(12, 12) └── mergeSort(14, 15
完整排序: 通过不断合并子数组,最终得到完全排序的数组 _MergeSort 函数 是递归函数,负责实际的排序工作。 计算中间点 mid,对左右两半 [begin, mid] 和 [mid+1, end] 分别递归调用 _MergeSort 进行排序。 MergeSort 函数 是主接口函数,负责初始化和释放临时数组。 动态分配与原数组相同大小的临时数组 tmp。 调用 _MergeSort 函数进行排序。 2.逻辑图 void _MergeSort(int* a, int begin, int end, int* tmp) { //划分 if (begin >= end)//只有一个元素不用划分 return; int mid = (begin + end) / 2;//首尾下标相加除2得到中间点下标 _MergeSort(a, begin, mid, tmp);//递归划分左半区域
The default is -1, which sorts along the last axis.kind:{‘quicksort’, ‘mergesort’, ‘heapsort’, ‘stable Note that both ‘stable’ and ‘mergesort’ use timsort or radix sort under the covers and, in general, the timsort’ is actually used, even if ‘mergesort’ is specified. On random data timsort is almost identical to mergesort. ‘mergesort’ and ‘stable’ are mapped to radix sort for integer data types.
return 0; // 归并排序 int[] temp = new int[len]; return mergeSort (array, 0, len-1, temp); } // 归并排序 private static int mergeSort(int[] array, int left (array, left, mid, temp); int rightPairs = mergeSort(array, mid+1, right, temp); (nums, 0, nums.length - 1); return (int) (cnt % 1000000007); } private void mergeSort(int[] nums , int l, int h) { if (h - l < 1) return; int m = l + (h - l) / 2; mergeSort(nums,
int vim=0; int reversePairs(vector<int>& record) { ret.resize(record.size()); mergesort int>&nums,int low,int high) { if(low>=high) return; int mid=(low+high)/2; mergesort (nums,low,mid); mergesort(nums,mid+1,high); merge(nums,low,high,mid); } int vim=0; int reversePairs(vector<int>& record) { ret.resize(record.size()); mergesort (nums,low,mid); mergesort(nums,mid+1,high); merge(nums,low,high,mid); }
tmp; public: vector<int> sortArray(vector<int>& nums) { tmp.reserve(nums.size()); mergesort (nums,0,nums.size()-1); return nums; } void mergesort(vector<int>& nums,int left,int right) { if(left >= right) return; int mid = (right + left)>>1; mergesort (nums,left,mid); mergesort(nums,mid+1,right); int cur1 = left, cur2 = mid + 1, i = 0; (nums,0,n-1); return ret; } void mergeSort(vector<int>& nums,int left,int right)
(1)递归划分: 计算数组中点 m ,递归划分左子数组mergesort(l, m)和右子数组mergesort(m + 1, r); 当 l==r 时,代表子数组长度为 1 ,此时终止划分,开始合并; vector<int> mergesort(const vector<int> &vec, int l, int r) { if (l == r) { return vector<int>{ vec[l]}; } int mid = (l + r) / 2; auto vec1 = mergesort(vec, l, mid); auto vec2 = mergesort(vec sl1 := mergesort(sl, l, mid) sl2 := mergesort(sl, mid+1, r) return merge(sl1, sl2) } 验证代码: package main import ( "fmt" ) func main() { fmt.Println(mergesort([]int{2}, 0, 0)) fmt.Println(mergesort
int reversePairs(int[] nums) { int n = nums.length; tmp = new int[n]; return mergesort (nums,0,n-1); } private int mergesort(int[] nums, int left, int right){ int ret if(left >= right) return 0; int mid = (right + left) / 2; //左右两边找翻转对 ret += mergesort (nums,left,mid); ret += mergesort(nums,mid+1,right); //一左一右找翻转对: 降序版本 //输入数组中的所有数字都在 (nums,0,n-1); } 一左一右找翻转对: 升序版本: private int mergesort(int[] nums, int left, int right){
归并排序(英语:Merge sort,或mergesort),是建立在归并操作上的一种有效的排序算法,效率为 {\displaystyle O(n\log n)} {\displaystyle O( a[p1++]; while(p2<=e) tmp[pb++] = a[p2++]; for(int i=0;i<e-s+1;++i) a[s+i] = tmp[i]; } void MergeSort (int a[],int s,int e,int tmp[]) { if(s<e){ int m = s+(e-s)/2; MergeSort(a,s,m,tmp); MergeSort( } } int a[10] = {10,9,8,7,6,5,4,3,2,1}; int b[10]; int main() { int size=sizeof(a)/sizeof(int); MergeSort