合并排序算法主要采用了递归的思想,将待排序的数组递归地进行二分,直到最后只剩下一个元素。一个元素的数组当然是有序的。然后再合并两个已经排好序的数组,进而达到对整个数组排序的效果。
对于两个已经排好序的数组,合并的实现都在Merge_sort中。其中用到了一点小技巧(假设数组是从小到大的),在数组最后添加一个很大的元素,这样做可以减少比较的步骤,简化程序,提高效率。
注意:malloc的用法。请比较一下:
int * pData1 = malloc((mid-begin+1+1)*sizeof(int));
和
int * pData1 = malloc(mid-begin+1+1);//错误
传入的参数一定是字节数。在C++中就不存在这样的考虑,应为在分配内存时就指定了类型。
Demo程序如下:
// Merge-sort algorithm implementation
#ifdef __cplusplus
#include <iostream>
using namespace std;
#else
#include <stdlib.h>
#include <stdio.h>
#endif //__cplusplus
// 定义一个宏,表示最大的整数。
#define MAX_INT_NUM 0x7FFFFFFF
#define LENGTH 10
#define LENGTH1 5
#define LENGTH2 5
void Merge(int *data , int begin , int mid , int end);
void Merge_sort(int *data , int begin , int end);
int main()
{
int data[LENGTH] = {12 , 45 , 46 , 1 , 78 , 98 , 15 , 21 , 32 , 77};
int i = 0;
Merge_sort(data , 0 , sizeof(data)/sizeof(int)-1);
while (i<sizeof(data)/sizeof(int))
{
#ifdef __cplusplus
cout<<data[i]<<" ";
#else
printf("%d " , data[i]);
#endif //__cplusplus
i++;
}
return 0;
}
void Merge(int *data , int begin , int mid , int end)
{
// 多分配一个int类型的空间,存储最大的整型数,简化程序
#ifdef __cplusplus
int * pData1 = new int[mid-begin+1+1];
int * pData2 = new int[end-mid+1];
#else
int * pData1 = malloc((mid-begin+1+1)*sizeof(int));
int * pData2 = malloc((end-mid+1)*sizeof(int));
#endif //__cplusplus
int index , i , left ,right;
i = 0;
index = begin;
while (index<=mid)
{
pData1[i] = data[index];
i++;
index++;
}
pData1[i] = MAX_INT_NUM;
i = 0;
while (index<=end)
{
pData2[i] = data[index];
i++;
index++;
}
pData2[i] = MAX_INT_NUM;
i = 0;
left = right = 0;
while (i<(end-begin+1))
{
if (pData1[left]<=pData2[right])
{
data[i+begin] = pData1[left];
left++;
}
else
{
data[i+begin] = pData2[right];
right++;
}
i++;
}
#ifdef __cplusplus
delete []pData1;
delete []pData2;
#else
free(pData1);
free(pData2);
#endif //__cplusplus
}
void Merge_sort(int *data , int begin , int end)
{
int mid;
if (begin<end)
{
mid = (end + begin)/2;
Merge_sort(data , begin , mid);
Merge_sort(data , mid+1 , end);
Merge(data , begin , mid , end);
}
}