原地归并排序

排序讨论举例

 

 

1 | 3 5 7 | 2 4 6 8

 

1 2 | 5 7 | 3 4 6 8

 

1 2 3 | 7 | 4 5 6 8

 

1 2 3 4 | 5 6 7 8

 

1 2 3 4 5 6 7 8

 

1.l<r,不交换

2.l>r,交换,并把l查到r序列的顺序位置

 

O(n^2)

 

------------------------------------------

 

1 | 3 5 7 | 2 4 6 8

 

1 2 | 5 7 | 3 4 6 8

 

1 2 3 4 | 5 7 | 6 8

 

1 2 3 4 5 | 7 | 6 8

 

1 2 3 4 5 6 | 7 | 8

 

1 2 3 4 5 6 7 8

 

1.l<r,不交换

2.l>r,则开始比较l与r序列大小,把小于l的全部换至l前

(从后往前换,如果到头了,就一直和头换)

 

关键 : 下标的变换

1.如果只有1个元素交换,那么l++,r不变

2.如果多个交换,则l+=n(交换个数),le+=n,j+=n

 

O(n)

 

-----------------------------------------

 

1 | 3 5 | 2 4 6 8

 

1 2 | 5 | 3 4 6 8

 

1 2 | 4 | 3 5 | 6 8

 

1 2 3 4 | 5 | 6 8

 

-----------------------------------------

 

1 | 3 5 | 2 4 4 6 8

 

1 2 | 5 | 3 4 4 6 8

 

1 2 3 4 4 | 5 | 6 8

 

 

附有代码

 

void swap(int key[], int l, int r) { int temp = key[l]; key[l] = key[r]; key[r] = temp; } void reverse(int x[], int l, int r) { int i; for (i = l; i <= (l + r) / 2; i++) swap(x, i, r - (i - l)); } void revSeq(int x[], int l, int m, int r) { reverse(x, l, r); reverse(x, l, r - m + l - 1); reverse(x, r - m + l, r); } void merge(int x[], int l, int m, int r) { int i = l, j = m + 1; int ie = m, je = r; while (i <= ie && j <= je && x[ie] > x[j]) { if (x[i] <= x[j]) i++; else { int k; for (k = j; k <= je && x[i] > x[k]; k++) ; if (k - j == 1) { swap(x, i, j); i++; } else { revSeq(x, i, ie, k - 1); i += k - j; ie += k - j; j += k - j; } } } } void mergeSort(int x[], int l, int r) { if (l < r) { int m = (l + r) / 2; mergeSort(x, l, m); mergeSort(x, m + 1, r); merge(x, l, m, r); } } void printX(int x[], int n) { int i; for (i = 0; i < n; i++) printf("%d ", x[i]); printf("/n"); } int main() { int x[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; int sx = sizeof (x) / sizeof (x[0]); int y[] = {1, 3, 5, 7, 2, 4, 6, 8}; int sy = sizeof (y) / sizeof (y[0]); mergeSort(x, 0, sx - 1); merge(y, 0, 3, 7); printX(x, sx); printX(y, sy); return 0; }  

你可能感兴趣的:(原地归并排序)