一、归并算法思想
归并算法是建立在归并操作的基础上的。归并操作是指将两个或者多个以上的有序序列合并成一个新的序列,得到的新序列仍然有序。假设待排序序列大小为n,则初始状态下待排序序列有n个有序的子序列,其中每个子序列的大小为1,经过一次“两两归并”后,待排序序列将包含多个有序的大小为2的子序列。。。以此类推,直到整个序列有序。
二、代码实现
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define DATA_SIZE 10
int* init_data(int size);
void print_data(int* pdata, int size);
void swap(int* pdata, int i, int j);
int max(int* pdata, int i, int j);
void do_sort(int *pdata, int size);
void merge(int *pdata, int idx1, int len1, int idx2, int len2);
void free_data(int *pdata);
int main()
{
int *pdata = init_data(DATA_SIZE);
if (NULL == pdata)
{
return -1;
}
puts("Before sort:");
print_data(pdata, DATA_SIZE);
do_sort(pdata, DATA_SIZE);
puts("After sort:");
print_data(pdata, DATA_SIZE);
free_data(pdata);
return 0;
}
int* init_data(int size)
{
int *pdata = (int*)malloc(size*sizeof(int));
if (NULL == pdata)
{
return NULL;
}
int i;
srand(time(NULL));
for (i = 0 ; i < size ; ++i)
{
pdata[i] = rand()%100;
}
return pdata;
}
void print_data(int* pdata, int size)
{
int i;
for (i = 0 ; i < size ; ++i)
{
printf("%4d", pdata[i]);
}
printf("\n");
}
void swap(int* pdata, int i, int j)
{
int tmp;
tmp = pdata[i];
pdata[i] = pdata[j];
pdata[j] = tmp;
}
int max(int* pdata, int i, int j)
{
return pdata[i] >= pdata[j] ? i : j;
}
void do_sort(int *pdata, int size)
{
int subseqlen = 1;
int subseqnum = size;
while (subseqlen < size)
{
int mergetime = subseqnum / 2;
int i;
for (i = 0 ; i < mergetime ; ++i)
{
int startidx1 = i*2*subseqlen;
int len1 = subseqlen;
int startidx2 = startidx1 + subseqlen;
int len2 = (size - startidx1 - len1) < subseqlen ? (size - startidx1 - len1) : subseqlen;
merge(pdata, startidx1, len1, startidx2, len2);
}
subseqlen *= 2;
subseqnum = (size + subseqlen - 1) / subseqlen;
}
}
void merge(int *pdata, int startidx1, int len1, int startidx2, int len2)
{
int *tmp;
tmp = (int*)malloc((len1+len2)*sizeof(int));
if (NULL == tmp)
{
return;
}
int idx1 = startidx1;
int idx2 = startidx2;
int tmpidx = 0;
while ((idx1 - startidx1) < len1 && (idx2 - startidx2) < len2)
{
if (pdata[idx1] < pdata[idx2])
{
tmp[tmpidx] = pdata[idx1];
idx1++;
}
else
{
tmp[tmpidx] = pdata[idx2];
idx2++;
}
tmpidx++;
}
if ((idx1 - startidx1) < len1)
{
while ((idx1 - startidx1) < len1)
{
tmp[tmpidx] = pdata[idx1];
idx1++;
tmpidx++;
}
}
else if ((idx2 - startidx2) < len2)
{
while ((idx2 - startidx2) < len2)
{
tmp[tmpidx] = pdata[idx2];
idx2++;
tmpidx++;
}
}
int j;
for (j = 0; j < len1+len2 ; ++j)
{
pdata[startidx1+j] = tmp[j];
}
free(tmp);
}
void free_data(int *pdata)
{
free(pdata);
pdata = NULL;
}