归并排序

来源:互联网 发布:vb 调用按钮事件 编辑:程序博客网 时间:2024/05/14 10:27

参考资料:百度百科

对一个数列归并排序,实际上就是把数组划分成一颗二叉树。自下而上的一小块一小块做快排,已达到O(k*nlogn)的效率进行排序(k为常数)。

过程如下:

偷懒借百度的图23333333

假设要排序的数组 a={10,4,6,3,8,2,5,7},先对其进行二分分解,得到一个二叉树。

如图:


分好树后从下而上的每一个父节点进行排序

原理:我们先假设一个父节点其左序号为l,右序号为r

   那么其左子节点的起始点为a[i],则i=l

   右子节点的起始点为a[j],则j=mid+1=(l+r)/2+1;

   执行下面的算法:

1.若a[i]>a[j],则让a[j]排到前面,j++,否则让a[i]排在前面,i++

2.判断i是否小于等于mid,j是否小于等于r,若都满足则返回第一步,否则执行第三步

3.如果左或右子节点有剩下没排的数,他们肯定时有序的,不用重排,直接跟在排好的数后。返回。

举例!!!

第一次排序是(10,4)这个父节点l=1,r=2,mid=(l+r)/2=1

那么其左子节点是(10)右子节点是(4),i=1,j=2;

显然a[i]>a[j],那么a[j]排在a[i]前面父节点变成(4),i++;

此时i=2>mid,加上剩下的数父节点为(4,10)返回。


第二次排序是(6,3)这个父节点l=3,r=4,mid=3

那么其左子节点是(3)右子节点是(6),i=3,j=4;

显然a[i]>a[j],那么a[j]排在a[i]前面父节点变成(3),i++;

此时i=4>mid,加上剩下的数父节点为(3,6)返回。


第三次排序是(4,10,3,6)这个父节点l=1,r=4,mid=2

那么其左子节点是(4,10)右子节点是(3,6),i=1,j=3;

显然a[i]>a[j],那么a[j]排在a[i]前面

父节点变成(3),j++;

此时j=4=r继续。

此时a[i]=4,a[j]=6,显然a[i]<a[j],那么a[i]排在a[j]前面

父节点变成(3,4),i++;

此时i=2=mid继续。

此时a[i]=10,a[j]=6,显然a[i]>a[j],那么a[j]排在a[i]前面

父节点变成(3,4,6),j++;

此时j=5>r,加上剩下的数父节点为(3,4,6,10)返回。

。。。。。。。。。。

。。。。。。。。。。

。。。。。。。。。。

类似的按此规则排序后,即可对整个数列排序。

效率稍差于快排,但十分稳定。

你可以在这里看到,归并排序的动态演示。点进去选择上面的merge,再点击左下角的三角,先create,再sort。

0 0
原创粉丝点击