三路归并算法的关键在于分割点的下标计算
package fenzhi;
public class MergeSortTest {
public static void main(String[] args) {
int[] data = new int[] { 5, 3, 6, 2, 16, 9, 4, 5, 3, 6, 2, 16, 9, 4, 7,10,11,15, 8,12,13,1,14,7,10,11,15, 8,12,13,1,14, 5, 3, 6, 2, 16, 9, 4, 7,10,11,15, 8,12,13,1,14};
print(data);
mergeSort(data);
System.out.println("排序后的数组:");
print(data);
}
public static void mergeSort(int[] data) {
sort(data,0,data.length -1);
}
public static void sort(int[] data, int left, int right) {
if (left >= right)
return;
// 找出中间索引
int center_first = left+((right-left)/3);
int center_next=right-(right-left)/3;
// 对左边1/3数组进行递归
sort(data, left, center_first);
// 对中间1/3数组进行递归
sort(data, center_first + 1, center_next);
// 对右侧1/3数组进行递归
sort(data,center_next+ 1, right);
// 合并
merge(data, left, center_first,center_next, right);
print(data);
}
public static void merge(int[] data, int left, int center_first,int center_next, int right) {
// 临时数组
int[] tmpArrList = new int[data.length];
// 三段数组的三个起点
int first=left;
int second = center_first+1;
int third=center_next+1;
//临时数组的起点
int num=left;
int tmp=left;
while (first <= center_first && second<=center_next&&third <= right) {
// 从三个数组中取出最小的放入临时数组
if (data[first] <= data[second]&&data[first]<=data[third]) {
tmpArrList[num] = data[first];
first++;
num++;
}
else if(data[second] <= data[first]&&data[second]<=data[third]){
tmpArrList[num] = data[second];
second++;
num++;
}
else {
tmpArrList[num] = data[third];
third++;
num++;
}
}
// 当有一个数组率先全部排进临时数组后,继续排剩下的两个数组
while (first <= center_first&&second<=center_next) {
if (data[first] <= data[second]) {
tmpArrList[num] = data[first];
first++;
num++;
}
else{
tmpArrList[num] = data[second];
second++;
num++;
}
}
while (second <= center_next&&third<=right) {
if (data[second] <= data[third]) {
tmpArrList[num] = data[second];
second++;
num++;
}
else{
tmpArrList[num] = data[third];
third++;
num++;
}
}
while (first <= center_first&&third<=right) {
if (data[first] <= data[third]) {
tmpArrList[num] = data[first];
first++;
num++;
}
else{
tmpArrList[num] = data[third];
third++;
num++;
}
}
//当两个数组全部排进临时数组后,只剩下一个数组
while (first <= center_first){
tmpArrList[num] = data[first];
first++;
num++;
}
while (second <= center_next){
tmpArrList[num] = data[second];
second++;
num++;
}
while(third<=right){
tmpArrList[num] = data[third];
third++;
num++;
}
// 将临时数组中的内容拷贝回原数组中
// (原left-right范围的内容被复制回原数组)
while (tmp <=right) {
data[tmp] = tmpArrList[tmp];
tmp++;
}
}
public static void print(int[] data) {
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + " ");
}
System.out.println();
}
}