(1)基本思想
归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
两个步骤:
1.分,当有序表只有一个元素,分解结束。
2.合,将两个有序表合并。
(2)代码实现
public static void mergeSort(int[] array) {
mergeSortFunc(array,0,array.length-1);
}
private static void mergeSortFunc(int[] array,int left,int right) {
if (left >= right) {
return;
}
int mid = (left+right)/2;
mergeSortFunc(array,left,mid); //先走左边
mergeSortFunc(array,mid+1,right); //再走右边
merge(array, left, right,mid); // 合并
}
private static void merge(int[] array,int start,int end,int mid) {
int s1 = start;
int s2 = mid+1;
int[] tmp = new int[end];
int k = 0; // 表示tmp数组的下标
while (s1 <= mid && s2 <= end) {
if (array[s1] <= array[s2]) {
tmp[k++] = array[s1++];
} else {
tmp[k++] = array[s2++];
}
}
while (s1 <= mid) {
tmp[k++] = array[s1++];
}
while (s2 <= mid) {
tmp[k++] = array[s2++];
}
for (int i = 0; i < tmp.length; i++) {
array[i+start] = tmp[i]; //将tmp数组的元素copy到array数组中
}
}
非递归实现归并排序
public static void mergeSort2(int[] array) {
int gap = 1;
while (gap < array.length) {
for (int i = 0; i < array.length; i += gap*2) {
int left = i;
int mid = left+gap - 1;
if (mid >= array.length) {
mid = array.length-1;
}
int right = mid+gap;
if (right >= array.length) {
right = array.length-1;
}
merge(array,left,right,mid);
}
gap *= 2;
}
}
(3)特性总结
1. 归并的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。
2. 时间复杂度:O(N*logN) 空间复杂度:O(N)
3. 稳定性:稳定