归并排序-就地排序

题目要求:对归并排序进行修改,要求合并过程的空间复杂度为O(1)

解题思路:

假设a[beg, mid]和b[mid+1,end]是两段有序的子段,分别记做A和B,现要对其进行合并

1) 首先对A进行搜索,找到比B[0]大的第一个位置,记录为i,即A[0~i-1] < B[0],而A[i] > B[0];

2) 对B进行搜索,找到大于A[i]的第一个位置,记录为j,则B[0~j-1]<B[i]

3) 将A[i,mid], B[0,j-1] 进行旋转,使得B[0,j-1]旋转到左边,得到B[0,j-1] A[i, mid]

4)A[i, mid] B[j, end]是原来问题的一个子问题,继续上述1)-3)的步骤

下面是具体实现的代码:

  1 #include <iostream>
  2 
  3 using namespace std;
  4 
  5  
  6 
  7 void reverse(int *array, int beg, int end)
  8 
  9 {
 10 
 11     while(beg < end)
 12 
 13     {
 14 
 15         int tmp = array[beg];
 16 
 17         array[beg] = array[end];
 18 
 19         array[end] = tmp;
 20 
 21         ++beg;
 22 
 23         --end;
 24 
 25     }
 26 
 27 }
 28 
 29  
 30 
 31 void rotate(int *array, int beg, int end, int len)
 32 
 33 {
 34 
 35     len = len % (end - beg + 1);
 36 
 37     reverse(array, beg, end - len);
 38 
 39     reverse(array, end - len + 1, end);
 40 
 41     reverse(array, beg, end);
 42 
 43 }
 44 
 45  
 46 
 47 void merge(int *array, int beg, int mid, int end)
 48 
 49 {
 50 
 51     int i = beg;
 52 
 53     int j = mid + 1;
 54 
 55     while(i <= end && j <=end && i < j)
 56 
 57     {
 58 
 59         while(i <= end && array[i] < array[j])
 60 
 61         {
 62 
 63             ++i;
 64 
 65         }        
 66 
 67         int k = j;
 68 
 69         while(j <= end && array[j] < array[i])
 70 
 71         {
 72 
 73             ++j;
 74 
 75         }        
 76 
 77         if(j > k)   // 注意这个条件
 78 
 79         {
 80 
 81             rotate(array, i, j-1, j-k);
 82 
 83         }
 84 
 85         
 86 
 87         i += (j -k + 1);
 88 
 89     }
 90 
 91 }
 92 
 93  
 94 
 95 void mergeSort(int *array, int beg, int end)
 96 
 97 {
 98 
 99     if(beg == end)
100 
101         return;
102 
103         
104 
105     int mid = (beg + end) >> 1;
106 
107     mergeSort(array, beg, mid);
108 
109     mergeSort(array, mid + 1, end);
110 
111     merge(array, beg, mid, end);
112 
113 }
114 
115  
116 
117 int main()
118 
119 {
120 
121     int array[] = {8, 7, 6, 5, 4, 3, 2, 1};
122 
123     int beg = 0;
124 
125     int end = sizeof(array) / sizeof(int) - 1;
126 
127     mergeSort(array, beg, end);
128 
129     
130 
131     for(int i=beg; i<=end; ++i)
132 
133     {
134 
135         cout << array[i] << " ";
136 
137     }
138 
139     cout << endl;
140 
141     
142 
143     return 0;
144 
145 }

 

posted @ 2016-01-25 22:23  Shirley_ICT  阅读(1316)  评论(0编辑  收藏  举报