归并排序的基本思想:将待排序列表的各个元素看作是长度为1的子列表,然后两两归并(归并:将两个或两个以上的子列表组合成一个新的有序表),得到
⌈
n
2
⌉
\lceil \frac{n}{2}\rceil
⌈2n⌉个长度为2或1的有序表;继续两两归并……,重复操作,直到合并成一个长度为n的有序表。
代码:
/**
*
*********************
* @Title: mergeSort
* @Description: TODO(Merge sort the data.)
*********************
*
*/
public void mergeSort(int paraStart, int paraEnd) {
if (paraStart < paraEnd) {
int tempMiddle = paraStart + (paraEnd - paraStart) / 2;
mergeSort(paraStart, tempMiddle);
mergeSort(tempMiddle + 1, paraEnd);
merge(paraStart, tempMiddle, paraEnd);
} // Of if
}// Of mergeSort
/**
*
*********************
* @Title: merge
* @Description: TODO(Merge the data.)
*********************
*
*/
public void merge(int paraStart, int paraMiddle, int paraEnd) {
int tempLength = paraEnd - paraStart + 1;
DataNode[] tempNodes = new DataNode[tempLength];
// Copy the data.
for (int i = 0; i < tempLength; i++) {
tempNodes[i] = data[i + paraStart];
} // Of for i
int tempMiddle = paraMiddle - paraStart;
int i = 0, j = tempMiddle + 1, k = paraStart;
// Merge
while (i <= tempMiddle && j < tempLength) {
if (tempNodes[i].key <= tempNodes[j].key) {
data[k++] = tempNodes[i++];
} else {
data[k++] = tempNodes[j++];
} // Of sort
} // Of while
// Copy the rest of the data.
while (i <= tempMiddle)
data[k++] = tempNodes[i++];
while (j < tempLength)
data[k++] = tempNodes[j++];
System.out.println("Merge from the index of " + paraStart + " to the index of " + paraEnd);
}// Of merge
/**
*********************
* Merge sort. Results are stored in the member variable data.
*********************
*/
/**
*
*********************
* @Title: mergeSortTest
* @Description: TODO(Test the method.)
*
*********************
*
*/
public static void mergeSortTest() {
int[] tempUnsortedKeys = { 5, 3, 6, 10, 7, 1, 9 };
String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);
System.out.println(tempDataArray);
tempDataArray.mergeSort(0, tempDataArray.length - 1);
System.out.println(tempDataArray);
}// Of mergeSortTest
运行结果:
时间复杂度分析:
测试序列的归并排序过程如图所示:
由此可得,归并排序也是基于分治思想,对于长度为
n
n
n的待排序序列,要进行
log
n
\log n
logn趟排序,且趟排序需要对
n
n
n个元素进行比较,所以归并排序的时间复杂度为
O
(
n
log
n
)
O(n\log n)
O(nlogn)。与平均时间复杂度相同的快速排序算法比较,归并排序需要
O
(
n
)
O(n)
O(n)的额为存储空间,但归并排序的效果好坏与输入元素序列无关,如果输入元素序列呈逆序或基本有序,快速排序算法的时间复杂度会增至
O
(
n
2
)
O(n^2)
O(n2),且空间复杂度增至
O
(
n
)
O(n)
O(n)。