我们常见的归并排序,又叫做2路归并排序
,相当于是将两个顺序表或链表合在一起的操作。如果我们通过二分法来实现,将个长的顺序表一直二分法一直分到最小的子序列,然后从最小子序列逐步合并成大的表,那么最后这个大表就是有序的了。
所以这是一个递归的过程,时间复杂度为 n l o g 2 n nlog_2n nlog2n
假设一个有序表的元素是0~n共n+1个元素,其中开始表示l,结束表示h,中间元素表示为m=(l+h)/2
递归表达式可以写为:
s o r t ( l , h ) = { l = h , 递 归 终 止 l < h , s o r t ( l , m ) ; s o r t ( m + 1 , h ) ; 并 合 并 sort(l,h)= \begin{cases} l = h,&递归终止\\ l
#include
#include
#define MAXLEN 100
int temp[MAXLEN] = {0}; //创建一个临时变量数组
int Mergelist(int arry[], int low, int mid,int high)
{
int tptr, lptr, hptr, i = 0;
tptr = 0; // 临时数组储存下标
lptr = low; // 左序列下标,low<=lptr<=mid
hptr = mid + 1; // 右序列下标,mid+1<=hptr<=high
while(lptr <= mid && hptr <= high) // 这三个while就是循环合并两个线性表
{
// 将左序列或右序列中,较小的存入临时数组里
if (arry[lptr] <= arry[hptr])
{
temp[tptr] = arry[lptr];
++lptr;
}
else
{
temp[tptr] = arry[hptr];
++hptr;
}
++tptr;
}
// 检测左序列是否添加完毕
while(lptr <= mid)
{
temp[tptr] = arry[lptr];
++lptr;
++tptr;
}
// 检测右序列是否添加完毕
while(hptr <= high)
{
temp[tptr] = arry[hptr];
++hptr;
++tptr;
}
// 将新序列覆盖原数组
for (; i < tptr; ++i)
{
arry[low+i]=temp[i];
}
}
int MergeSort(int arry[], int low, int high)
{
int mid;
if (low < high) // 可递归部分
{
mid = (low + high) / 2;
MergeSort(arry, low, mid); // 左序列
MergeSort(arry, mid+1, high); // 右序列
Mergelist(arry, low, mid, high); // 合并两序列
}
}
int main()
{
int a[7] = {6,5,3,7,2,1,4};
int i;
MergeSort(a, 0, 6);
for (i = 0; i < 7; ++i)
{
printf("%d ", a[i]);
}
return 0;
}