算法描述
归并排序是分治策略的一种体现,很多算法在结构上是可以递归的,为了解决一个问题,需要一次或多次递归调用自身来解决相关的子问题。归并排序需要额外的内存空间,是一种以空间换取时间的排序方法。
下例中采用二路归并,且在一段小数据时,使用插入法排序。
代码实现(C实现)
#include<stdio.h>
int insertsort(int * const p,int start,int end){
int key=0;
int i = 0;
int j = 0;
if(p == NULL || start > end || end - start< 1){
printf("array is empty or length of array is zero\n");
return 0;
}
for(i = 1 + start;i <= end;i++){
key = *(p+i);
j = i - 1;
while(j >= start && *(p + j) > key){
*(p+1+j) = *(p+j);
j--;
}
*(p + j + 1) = key;
}
return 1;
}
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include "sort.h"
#include "../common/io.h"
static int merge(int * const p,const int start,const int end){
if(p == NULL || start < 0 || end < 0 || start >= end){
return 0;
}
if(start + DEFAULT_KSTEP < end){
int mid = (start + end) / 2;
if(merge(p,start,mid) == 0) return 0;
if(merge(p,mid+1,end) == 0) return 0;
int * array_1 = (int *)malloc((mid + 2 - start)*sizeof(int));
int * array_2 = (int *)malloc((end + 1 - mid)*sizeof(int));
if(array_1 == NULL || array_2 == NULL){
if(array_1 != NULL){
free(array_1);
}
if(array_2 != NULL){
free(array_2);
}
return 0;
}
int k = 0;
for(k = 0;k < mid + 1 - start;k++){
array_1[k] = *(p + start + k);
}
array_1[mid + 1 -start] = INT_MAX;
for(k = 0;k < end - mid;k++){
array_2[k] = *(p + mid + 1 + k);
}
array_2[end - mid] = INT_MAX;
k = start;
int i=0,j=0;
//
while(array_1[i] < INT_MAX || array_2[j] < INT_MAX){
if(array_1[i] <= array_2[j]){
*(p + k) = *(array_1 + i);
i++;
}else{
*(p + k) = *(array_2 + j);
j++;
}
k++;
}
free(array_1);
free(array_2);
printSubArray(p,start,end);
}else{
//插入排序来实现小数据就地排序
insertsort(p,start,end);
}
return 1;
}
int merge_sort(int * const p,int length){
return merge(p,0,length-1);
}
测试程序:
#include <stdio.h>
#include "common/io.h"
#include "sort/sort.h"
int main(void){
int array[10] = {1,4,-1,90,12,45,6,45,43,8};
printArray(array,10);
merge_sort(array,10);
printArray(array,10);
}