归并排序图示
归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法,采用了分治法((Divide and Conquer))的思想。
大体分为 拆分 与 组合 两个步骤
拆分:将原始数组依次对半拆分,直至每个数组中只有一个数字,是分的过程。
组合:每两个数组中的数字排序后合并到一个数组中,直至合并成一个数组,是治的过程。
注意:拆分时,并不是真正的将原数组中的数取出来放入另一个数组,而是通过两个索引划分区段
程序运行时,先左递归拆分到最小单位,再右递归拆分到最小单位,然后递归组合,最终组合成的数组就是排序好的数组,如下图所示:
参考代码
拆分
public static void mergeSort(int[] arr
, int startIndex
, int endIndex
, int[] temp
) {
if (startIndex
>= endIndex
) return;
int mid
= (startIndex
+ endIndex
) / 2;
mergeSort(arr
, startIndex
, mid
, temp
);
mergeSort(arr
, mid
+ 1, endIndex
, temp
);
merge(arr
, startIndex
, mid
, endIndex
, temp
);
}
组合
public static void merge(int[] arr
, int startIndex
, int mid
, int endIndex
, int[] temp
) {
int left
= startIndex
;
int right
= mid
+ 1;
int t
= 0;
while (left
<= mid
&& right
<= endIndex
) {
if (arr
[left
] <= arr
[right
]) {
temp
[t
] = arr
[left
];
t
++;
left
++;
} else {
temp
[t
] = arr
[right
];
t
++;
right
++;
}
}
while (left
<= mid
) {
temp
[t
] = arr
[left
];
t
++;
left
++;
}
while (right
<= endIndex
) {
temp
[t
] = arr
[right
];
t
++;
right
++;
}
t
= 0;
while (startIndex
<= endIndex
) {
arr
[startIndex
] = temp
[t
];
startIndex
++;
t
++;
}
}
测试排序效果
public static void main(String
[] args
) {
int[] arr
= {3, 5, 8, 1, 2, 9, 4, 7, 6};
int[] temp
= new int[arr
.length
];
System
.out
.println("排序前:" + Arrays
.toString(arr
));
mergeSort(arr
, 0, arr
.length
- 1, temp
);
System
.out
.println("归并排序:" + Arrays
.toString(arr
));
}
归并排序涉及递归,所以将临时数组定义在外面,减少分配空间的次数,提高效率
1亿随机数测试排序时间
public static void main(String
[] args
) {
int[] arrTime
= new int[100000000];
for (int i
= 0; i
< 100000000; i
++) {
arrTime
[i
] = (int) (Math
.random() * 100000000);
}
long former
= System
.currentTimeMillis();
merge(arrTime
, 0, arrTime
.length
/ 2, arrTime
.length
- 1, new int[arrTime
.length
]);
long later
= System
.currentTimeMillis();
System
.out
.println("时间:" + (later
- former
) + " 毫秒");
}