是一种简单的排序方法。时间复杂度为
O(N*logN)。
思想:归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用
分治法(Divide and Conquer)的一个非常典型的应用。
首先考虑下如何将将二个有序数列合并。这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可。
可以看出合并有序数列的效率是比较高的,可以达到
O(n)。
解决了上面的合并有序数列问题,再来看归并排序,基本思路就是将数组分成二组A,B,如果这二组组内的数据都是有序的,那么就可以很方便的将这二组数据进行排序。如何让这二组组内数据有序了?
可以将A,B组各自再分成二组。依次类推,当分出来的小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的二个小组就可以了。这样通过先递归的分解数列,再合并数列就完成了归并排序。
归并排序的效率是比较高的,设数列长为N,将数列分开成小数列一共要logN步,每步都是一个合并有序数列的过程,时间复杂度可以记为O(N),故一共为
O(N*logN)。因为归并排序每次都是在相邻的数据中进行操作,所以归并排序在O(N*logN)的几种排序方法(快速排序,归并排序,希尔排序,堆排序)也是效率比较高的。
public
class
MergeSort {
public
static
final
int
CUTOFF
= 11;
public
static
void
main(String[] args) {
//
TODO
Auto-generated method stub
int
[] a;
int
n = 300;
// 生产随机数组
a =
new
int
[n];
Random rand =
new
Random();
for
(
int
i = 0; i < a.
length
; i++) {
a[i] = rand.nextInt(n);
}
//a = new int [] {33,10,80};
println(a);
long
s = System. nanoTime();
int
[] b = mergeSort(a);
long
dur = System. nanoTime() - s;
println(b);
System.
out
.println(dur);
}
public
static
int
[] mergeSort(
int
[] a) {
int
[] tmp =
new
int
[a.
length
];
split(a, tmp, 0, a.
length
-1);
return
tmp;
}
public
static
void
split(
int
[] a,
int
[] tmp,
int
left,
int
right) {
//System.out.println(left+","+right);
if
(left < right) {
int
center = (left + right) / 2;
//System.out.println(center);
split(a, tmp, left, center);
split(a, tmp, center + 1, right);
merge(a,tmp,left,center+1,right);
}
//System.out.println("返回");
}
public
static
void
merge(
int
[] a,
int
[] tmp,
int
lPos,
int
rPos,
int
rEnd){
//System.out.println("merge:"+lPos+","+rPos+","+rEnd);
int
lEnd = rPos -1;
int
tPos = lPos;
int
leftTmp = lPos;
while
(lPos <= lEnd && rPos <= rEnd){
if
(a[lPos] <= a[rPos]){
tmp[tPos++] = a[lPos++];
}
else
{
tmp[tPos++] = a[rPos++];
}
}
while
(lPos <= lEnd){
tmp[tPos++] = a[lPos++];
}
while
(rPos <= rEnd){
tmp[tPos++] = a[rPos++];
}
// copy the tmpArr back cause we need to change the arr array items.
for
( ; rEnd >= leftTmp; rEnd-- )
a[rEnd] = tmp[rEnd];
}
public
static
void
println(
int
[] a) {
System.
out
.print(
"["
);
for
(
int
i = 0; i < a.
length
; i++) {
System.
out
.print(a[i]);
if
(i != a.
length
- 1)
System.
out
.print(
","
);
}
System.
out
.println(
"]"
);
}
}