归并排序分析
归并排序(MergeSort),又称合并排序.
【工作原理】假如有7个记录,要对这7记录进行排序
1、把它这些记录每组2个(最后一组有可能只有1个),一共4组
2、分别把这4组排序好,再把这4组两两合并为1组,得到2组。
3、在合并的同时排序,使得得到的合并的后的每组都是有序的
4、将最后这两组合并成一组有序的序列。
【正确性】归并排序是一个典型的分治合并算法,对一个大小的记录序列排序,可以把记录划分成2个记录序列,如果这两个子序列还是不能直接排序,则一真划分,直到序列剩下2个素或者1个元素。分治完毕后再依次两两,直至合并成一个有序表。
【算法5 - 1】合并算法,该算法与数据结构算法2.7是相同的
void Merge(RcdType * SR,int i,int m,int n)
{
int index,j,k;
RcdType * TR = (RcdType *)malloc((n - i + 1)*sizeof(RcdType));
if (TR == NULL) exit(0);
/*复制记录*/
for (index = 0;index <= (n - i);index++)
{
TR[index] = SR[i + index];
}
j = 0; k = m + 1 - i;index = i;
/*选择插入*/
while(j <= m - i && k <= n - i)
{
if (TR[j].key <= TR[k].key)
{
SR[index++] = TR[j++];
}
else SR[index++] = TR[k++];
}
/*插入剩余*/
while (j <= m - i)
{
SR[index++] = TR[j++];
}
/*插入剩余*/
while (k <= n - i)
{
SR[index++] = TR[k++];
}
free(TR);TR = NULL;
}
【算法5 - 2】合并排序
void MergeSort(SqList * L,int l,int r)
{
if (l < r)
{ /*分治*/
MergeSort(L,l,(l + r)/2);
MergeSort(L,(l + r )/2 + 1,r);
/*合并*/
Merge(L->r,l,(l + r)/2,r);
}
}
【算法分析】
如果问题规模为T(n),则分治过程中分成了两个子问题每个子问题的规模是1/2 * T(n/2)
合并排序的运行时间可以分解为:
分解:就是算出中间位置
解决:递归解决两个子问题,时间为1/2 * T(n/2)
合并:我们注意到,在一个含有n个元素的子数组上,Merge过程的运行时间为O(n),
所以得出下面等式
由于O(n)是线性关系,不妨设O(n) = cn;
每一层的总规模是cn,一共有logn + 1层,那么复杂度为cn*logn,所以得出O(nlogn),在演示的过程也可以看归并排序也是一种稳定的排序算法。同时不难发现合并排序的空间复杂度是为O(n).一些数据结构的定义见:
http://hi.baidu.com/niesongsong/blog/item/a64dfbafdf71f0f3fbed50b2.html