还记得学习c语言的时候,老师让你们写的小程序吗。给你两个从小到大的有序数组,然后将这两个数组合并成
一个从小到大的有序数组,归并排序主要就是运用了这种思想。
你可以想象将这个序列的每个元素先变成一个完全二叉树的叶子点,然后叶子点和叶子点比较形成有序序列,然
后有序序列和有序序列比较形成大的有序序列,最后序列的所有元素都加入进来,形成一个最终的有序序列
示例演示:
1,2,4,4,5,7,9
1,2,4,9 4,5,7
2,4 1,9 4,5 7
2 4 1 9 5 4 7
由上面的演示可以看出,归并排序是一个稳定的排序 ,那么归并排序的算法时间复杂度也可以大概的猜一下呢,二叉树,深度,哈哈,是不是有什么感觉
算法步骤:
1.不断地分解序列,每次都折半划分,直到划分到每一个子序列只有一个元素为止
2.不断地将划分的子序列量量合并后排序
3.返回排序好的序列
算法c语言实现:
#include <stdlib.h>
#include <stdio.h>
void
Merge(
int
sourceArr[],
int
tempArr[],
int
startIndex,
int
midIndex,
int
endIndex)
{
int
i = startIndex, j=midIndex+1, k = startIndex;
while
(i!=midIndex+1 && j!=endIndex+1)
{
if
(sourceArr[i] >= sourceArr[j])
tempArr[k++] = sourceArr[j++];
else
tempArr[k++] = sourceArr[i++];
}
while
(i != midIndex+1)
tempArr[k++] = sourceArr[i++];
while
(j != endIndex+1)
tempArr[k++] = sourceArr[j++];
for
(i=startIndex; i<=endIndex; i++)
sourceArr[i] = tempArr[i];
}
//内部使用递归
void
MergeSort(
int
sourceArr[],
int
tempArr[],
int
startIndex,
int
endIndex)
{
int
midIndex;
if
(startIndex < endIndex)
{
midIndex = (startIndex + endIndex) / 2;
MergeSort(sourceArr, tempArr, startIndex, midIndex);
MergeSort(sourceArr, tempArr, midIndex+1, endIndex);
Merge(sourceArr, tempArr, startIndex, midIndex, endIndex);
}
}
int
main(
int
argc,
char
* argv[])
{
int
a[8] = {50, 10, 20, 30, 70, 40, 80, 60};
int
i, b[8];
MergeSort(a, b, 0, 7);
for
(i=0; i<8; i++)
printf
(
"%d "
, a[i]);
printf
(
"\n"
);
return
0;
}
(来源百度百科)
时间复杂度:开始的时候说了,可以想象为一颗递归完全二叉树,自叶子节点向根节点构建,高度为log2n,每一层的总比较次数为N
空间复杂度:在任何时刻只需要一个临时数组即可,该数组任意部分都可以被使用,这样的话,O(n)即可
稳定性:上面分析过了,稳定。
排序算法之七--归并排序
最新推荐文章于 2021-04-07 00:37:05 发布