分治归并排序
Posted cccv
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分治归并排序相关的知识,希望对你有一定的参考价值。
1 void Solution::devideConquerSort(vector<int>& vec) 2 { 3 int left = 0; 4 int right = vec.size() - 1; 5 mergeSort(vec, left, right); 6 } 7 8 void Solution::mergeSort(vector<int>& vec, int left, int right) 9 { 10 if(left < right) 11 { 12 int mid = (left+right) / 2; 13 mergeSort(vec, left, mid); 14 mergeSort(vec, mid+1, right); 15 merge(vec, left, mid, right); 16 } 17 } 18 19 void Solution::merge(vector<int>& vec, int left, int mid, int right) 20 { 21 int leftnums = mid - left + 1; 22 int rightnums = right - mid; 23 24 int leftarr[leftnums+1], rightarr[rightnums+1]; 25 int j = left; 26 int i = 0; 27 for(i = 0; i < leftnums; i++) 28 { 29 leftarr[i] = vec[j]; 30 j++; 31 } 32 leftarr[i] = INT_MAX; // 足够大的数作为哨兵 33 34 j = mid + 1; 35 for(i = 0; i < rightnums; i++) 36 { 37 rightarr[i] = vec[j]; 38 j++; 39 } 40 rightarr[i] = INT_MAX; 41 42 i = 0; 43 j = 0; 44 for(int k = left; k < right + 1; k++) 45 { 46 if(leftarr[i] <= rightarr[j]) 47 { 48 if(leftarr[i] == INT_MAX) 49 { 50 // 如果此时leftarr[i]为INT_MAX 51 // 说明此时rightarr的元素也全为INT_MAX 52 // 为了防止下标i溢出 53 for(k; k < right + 1; k++) 54 { 55 vec[k] = INT_MAX; 56 } 57 break; 58 } 59 vec[k] = leftarr[i]; 60 i++; 61 } else 62 { 63 vec[k] = rightarr[j]; 64 j++; 65 } 66 } 67 }
分治模式在每层递归时都有三个步骤:
一:分解原问题为若干子问题,这些子问题都是原问题的规模较小的实例
二:解决这些子问题,递归地求解各个子问题。
三:合并这些子问题的解,使成为原问题的解
比如上述算法,将对一个数组排序的问题不断切分为更小的排序问题,直到最后(left<right),此时所有实例都是有序的,因为只有一个元素,如果有不理解的地方画一画图就很清晰了
归并排序:
一:分解-待排序的n个元素的序列各具n/2个元素的两个子序列
二:解决-使用归并排序递归地排序两个子序列
三:合并-合并两个已排序的子序列以产生已排序的答案
因为就我而言,我已经大致理解了,所以没有过多解释说明备注,如果有需要的话,请留言。
以上是关于分治归并排序的主要内容,如果未能解决你的问题,请参考以下文章