归并算法详解
void testMergeSort(){
int length = 300;
int array[length];
int j = 0;
for (int i = length; i > 0; i--) {
array[j++] = i;
}
printf("\n");
for (int j = 0; j < sizeof(array)/sizeof(int); j++) {
printf("the array is %d\n", array[j]);
}
#if 1 - 方法不太好
//mergeSort(array, (int)sizeof(array)/sizeof(int));//147
#endif
#if 1 - 方法实现较好
mergeSortOptimize(array, (int)sizeof(array)/sizeof(int));//147
#endif
printf("\n");
for (int j = 0; j < sizeof(array)/sizeof(int); j++) {
printf("the array is %d\n", array[j]);
}
}
/* 此实现会在每个递归中创建一个数组 如果算法要执行NLogn次 就会创建NLogn个临时数组 比较消耗资源 */
void mergeSort(int arr[], int length){
//O(NlogN)
if (length <= 1) {
return ;
}
static int calculateCount = 0;
int arra[length];
for (int j = 0; j < length; j++) {
arra[j] = arr[j];
}
int deleave = length / 2;
mergeSort(arra, deleave);
mergeSort(arra+deleave, length - deleave);
printf("\n");
for (int j = 0; j < length; j++) {
printf("the arr is %d\n", arra[j]);
}
int lminp = 0;
int rminp = deleave;
#if 0 - 不好循环实现方式
for (int i = 0; i < length; i++) {
printf("calculateCount is %d\n", calculateCount++);
int min = 0;
if (lminp < deleave && rminp < length) {
if (arra[lminp] < arra[rminp]) {
min = arra[lminp];
arr[i] = min;
lminp++;
}else{
min = arra[rminp];
arr[i] = min;
rminp++;
}
continue;
}
if (lminp < deleave) {
min = arra[lminp];
arr[i] = min;
lminp++;
continue;
}
if (rminp < length) {
min = arra[rminp];
arr[i] = min;
rminp++;
continue;
}
}
#endif
#if 1 - 较好的循环实现方式
int sortPosition = 0;
//因为每个子序列已经排序 所以每个都从起点开始判断 不能使用左边从左边起点开始递加 右边从右边终点开始递减
//对于归并排序分成的两个子序列虽然每个子序列都已经各自排序但是左侧子序列和右侧子序列的值并没有联系
while (lminp < deleave && rminp < length) {
if (arra[lminp] < arra[rminp]) {
arr[sortPosition++] = arra[lminp++];
}else{
arr[sortPosition++] = arra[rminp++];
}
printf("calculateCount is %d\n", calculateCount++);
}
while (lminp < deleave) {
arr[sortPosition++] = arra[lminp++];
printf("calculateCount is %d\n", calculateCount++);
}
while (rminp < length) {
arr[sortPosition++] = arra[rminp++];
printf("calculateCount is %d\n", calculateCount++);
}
#endif
// printf("\n");
// for (int j = 0; j < length; j++) {
// printf("the arr is %d\n", arr[j]);
// }
}
/** 此方法为优化过的归并在递归过程中只存在一个临时数组 */
void mergeSortOptimize(int arr[], int length){
int *p = (int *)malloc(length*sizeof(int));
mergeSortOptimizeInner(arr, p, length);
printf("\n");
for (int j = 0; j < length; j++) {
printf("the arr is %d\n", arr[j]);
}
free(p);
}
void mergeSortOptimizeInner(int arr[], int tempArr[], int length){
if (length <= 1) {
return ;
}
static int calculateCount = 0;
int deleave = length / 2;
mergeSortOptimizeInner(arr, tempArr, deleave);
mergeSortOptimizeInner(arr + deleave, tempArr, length - deleave);
printf("\n");
for (int j = 0; j < length; j++) {
printf("the arr is %d\n", arr[j]);
}
int lminp = 0;
int rminp = deleave;
int sortPosition = 0;
while (lminp < deleave && rminp < length) {
if (arr[lminp] < arr[rminp]) {
tempArr[sortPosition++] = arr[lminp++];
}else{
tempArr[sortPosition++] = arr[rminp++];
}
printf("calculateCount is %d\n", calculateCount++);
}
while (lminp < deleave) {
tempArr[sortPosition++] = arr[lminp++];
printf("calculateCount is %d\n", calculateCount++);
}
while (rminp < length) {
tempArr[sortPosition++] = arr[rminp++];
printf("calculateCount is %d\n", calculateCount++);
}
printf("\n");
for (int j = 0; j < length; j++) {
printf("the arr is %d\n", arr[j]);
arr[j] = tempArr[j];
}
}