以前写过归并排序的算法,但是时间过了好久,忘记怎么写的了,(也是醉了)。正好复习算法的时候遇到这个问题,就重新写了一下,把遇到的一些问题顺便记录一下。
核心就是用两个子数组记录分割后的两个数组中的变量, 然后依次比较大小即可。
这里有个细节需要注意一下,
arr_temp1[mid + 1 - low] = INT_MAX;
这段代码,用来设置一个哨兵, 用这种方法可以避免判断数组是否为空了
具体的算法的伪代码可以参考《算法导论》 Chapter 2 算法基础, P17
源代码如下:
// =====================【归并排序 】==================
// @ author : zhyh2010
// @ date : 20150606
// @ version : 1.0
// @ description :
// =====================【归并排序】==================
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define NUM 20
int arr[NUM] = { 0 };
int arr_temp1[NUM] = { 0 };
int arr_temp2[NUM] = { 0 };
void init()
{
time_t tm;
time(&tm);
srand((unsigned int)tm);
int max_item = 100;
for (int i = 0; i != NUM; i++)
arr[i] = rand() % max_item;
}
void display(int * arr)
{
for (int i = 0; i != NUM; i++)
printf("%-10d", arr[i]);
printf("\n");
}
void merge(int low, int mid, int high)
{
for (int ii = 0; ii != mid + 1 - low; ii++)
{
arr_temp1[ii] = arr[low + ii];
}
arr_temp1[mid + 1 - low] = INT_MAX;
for (int ii = 0; ii != high - mid; ii++)
{
arr_temp2[ii] = arr[mid + 1 + ii];
}
arr_temp2[high - mid] = INT_MAX;
int i = 0;
int j = 0;
for (int k = low; k != high + 1; k++)
{
if (arr_temp1[i] < arr_temp2[j])
arr[k] = arr_temp1[i++];
else
arr[k] = arr_temp2[j++];
}
}
void mergeSort(int low, int high)
{
if (low >= high)
return;
int mid = (low + high) / 2;
mergeSort(low, mid);
mergeSort(mid + 1, high);
merge(low, mid, high);
}
void main()
{
init();
printf("归并排序前\n");
display(arr);
mergeSort(0, NUM - 1);
printf("归并排序后\n");
display(arr);
}
时间: 2024-10-11 22:42:59