算法描述:
通过将乱序的数据划分为某一长度的归并段,并使得归并段中的数据有序,然后在对归并段进行扩充,最后合并为一个有序的归并段。归并的核心思想运用的是分治法的思想,分的思想是将原始数据划分为若干个段,治的思想是分别对各个段进行排序。递归进行,直至整个数据合并为一个段。
这里实现的是二路归并,下面是二路归并实现的图解:
由图所示,采用分治法很容易就将乱序的数据排序好,而且归并排序的最好、最坏、平均的时间复杂度均为O(nlogn)。下面就给出实现的代码:
void Marge(int *data, int len, int width)
{
int low1 = 0;
int high1 = low1 + width - 1;
int low2 = high1 + 1;
int high2 = low2 + width - 1 > len - 1 ? len -1, low2 + width - 1;
int count = 0;
int *s = (int *)malloc(sizeof(int) * len);
assert(s != NULL);
while(low1 < len && low2 < len)
{
while(low1 <= high1 && low2 <= high2)
{
if(data[low1] < data[low2]
{
s[count++] = data[low1++];
}
else
{
s[count++] = data[low2++]
}
}
while(low1 <= high1)
{
s[count++] = data[low1++];
}
while(low2 <= high2)
{
s[count++] = data[low2++];
}
low1 = high2 + 1;
high1 = low1 + width - 1 > len - 1 ? len - 1 : low1 + width - 1;
low2 = high1 + 1;
high2 = low2 + width - 1 > len - 1 ? len - 1 : low2 + width - 1;
}
while(low1 <= high1)
{
s[count++] = data[low1++];
}
int i = 0;
for(i; i < len; i++)
{
data[i] = s[i];
}
free(s);
}
void MargeSort(int *data, int len)
{
if(data == NULL || len <= 0)
{
return;
}
int i = 1;
for(i; i < len; i *= 2)
{
Marge(data, len, i);
}
}
- 在代码中我们使用了额外的空间,即他的空间复杂度为O(n),可知归并排序是以空间来换取时间提高效率。