要点
- 时间复杂度:平均情况O(nlogn);最好情况(nlogn);最坏情况O(nlogn)
- 空间复杂度:O(n)
- 归并排序是一种稳定的排序方式
- 基本思想:假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到[n/2]([x]表示不小于x的最小整数)个长度为2或1的有序子序列;再两两归并,如此重复,直至得到一个长度为n的有序序列为止,这种排序方法称为2路归并排序
基本思路
- 待排记录一分为二(直到待排记录只剩下一个,返回本身)
- 对前半部分归并排序
- 对后半部分归并排序
- 合并前后两部分有序序列:定义两个指针p1,p2分别指向前后两部分的起始位置,再新建一个能够容下两部分的数组,比较两个指针指向的关键字,较小的关键字依序存储到新建数组中,并且该关键字的指针向后移动,另一指针保持不变,直到所有记录存储到新建数组中
- 新建数组中的关键字依序存储回原数组的对应位置
递归实现
public void mergeSort(int sr[], int s, int t) {
if (s == t)
return;
else {
int m = (s + t) / 2;
mergeSort(sr, s, m);
mergeSort(sr, m + 1, t);
merge(sr, s, m, t);
}
}
private void merge(int sr[], int s, int m, int t) {
int trp = 0, lp = s, rp = m + 1;
int[] tr = new int[t - s + 1];
while (lp <= m && rp <= t) {
if (sr[lp] < sr[rp]) {
tr[trp++] = sr[lp++];
} else {
tr[trp++] = sr[rp++];
}
}
if (lp <= m) {
for (int i = 0; i <= m - lp; i++)
tr[trp++] = sr[lp++];
}
if (rp <= t) {
for (int i = 0; i <= t - rp; i++)
tr[trp++] = sr[rp++];
}
for (int i = 0; i < tr.length; i++) {
sr[i + s] = tr[i];
}
}
非递归实现