分治归并排序

 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个元素的两个子序列

二:解决-使用归并排序递归地排序两个子序列

三:合并-合并两个已排序的子序列以产生已排序的答案

因为就我而言,我已经大致理解了,所以没有过多解释说明备注,如果有需要的话,请留言。

猜你喜欢

转载自www.cnblogs.com/cccv/p/algorithm_002.html