参考资料:百度百科
对一个数列归并排序,实际上就是把数组划分成一颗二叉树。自下而上的一小块一小块做快排,已达到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。