排序七:归并排序
基本思想:
将两个或两个以上的有序序列合并为一个新的有序序列:
有序序列 V[1] ... V[m] 和 V[m+1] ... V[n] ——> V[1] ... V[n]
这种方法称为2路归并。
将3个有序序列归并为一个新的有序序列,称为3路归并。
将有多个有序序列归并为一个新的有序序列,称为多路归并。
#include <stdio.h> #include <malloc.h> void println(int array[], int len) { int i = 0; for(i=0; i<len; i++) { printf("%d ", array[i]); } printf("\n"); } void swap(int array[], int i, int j) { int temp = array[i]; array[i] = array[j]; array[j] = temp; } void Merge(int src[], int des[], int low, int mid, int high) { int i = low; int j = mid + 1; int k = low; while( (i <= mid) && (j <= high) ) { if( src[i] < src[j] ) { des[k++] = src[i++]; } else { des[k++] = src[j++]; } } while( i <= mid ) { des[k++] = src[i++]; } while( j <= high ) { des[k++] = src[j++]; } } void MSort(int src[], int des[], int low, int high, int max) { if( low == high ) { des[low] = src[low]; } else { int mid = (low + high) / 2; int* space = (int*)malloc(sizeof(int) * max); if( space != NULL ) { MSort(src, space, low, mid, max); MSort(src, space, mid+1, high, max); Merge(space, des, low, mid, high); } free(space); } } void MergeSort(int array[], int len) // O(n*logn) { MSort(array, array, 0, len-1, len); } int main() { int array[] = {21, 25, 49, 25, 16, 8}; int len = sizeof(array) / sizeof(*array); println(array, len); MergeSort(array, len); println(array, len); return 0; }
#include <stdlib.h> #include <stdio.h> void Merge(int sourceArr[],int tempArr[], int startIndex, int midIndex, int endIndex) { int i = startIndex, j=midIndex+1, k = startIndex; while(i!=midIndex+1 && j!=endIndex+1) { if(sourceArr[i] >= sourceArr[j]) tempArr[k++] = sourceArr[j++]; else tempArr[k++] = sourceArr[i++]; } while(i != midIndex+1) tempArr[k++] = sourceArr[i++]; while(j != endIndex+1) tempArr[k++] = sourceArr[j++]; for(i=startIndex; i<=endIndex; i++) sourceArr[i] = tempArr[i]; } //内部使用递归 void MergeSort(int sourceArr[], int tempArr[], int startIndex, int endIndex) { int midIndex; if(startIndex < endIndex) { midIndex = (startIndex + endIndex) / 2; MergeSort(sourceArr, tempArr, startIndex, midIndex); MergeSort(sourceArr, tempArr, midIndex+1, endIndex); Merge(sourceArr, tempArr, startIndex, midIndex, endIndex); } } int main(int argc, char * argv[]) { int a[8] = {50, 10, 20, 30, 70, 40, 80, 60}; int i, b[8]; MergeSort(a, b, 0, 7); for(i=0; i<8; i++) printf("%d ", a[i]); printf("\n"); return 0; }
小结:
- 希尔排序,快速排序,归并排序将算法的时间复杂度提高到了O(n*logn)
- 希尔排序和快速排序的排序结果都是不稳定的
- 归并排序的排序结果是稳定的