排序算法-归并排序
将两个的有序数列合并成一个有序数列,我们称之为"归并"。归并排序(Merge Sort)就是利用归并思想对数列进行排序。
归并排序的时间复杂度和稳定性
归并排序时间复杂度
归并排序的时间复杂度是O(NlogN)。
假设被排序的数列中有N个数。遍历一趟的时间复杂度是O(N),需要遍历多少次呢?
归并排序的形式就是一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的可以得出它的时间复杂度是O(NlogN)。
归并排序稳定性
归并排序是稳定的算法,它满足稳定算法的定义。
算法稳定性
– 假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!
java代码实现
public class MergeSort {
public static void mergeSortUp2Down(int[] nums, int start, int end, int[] temp) {
if (start >= end) {
return;
}
int mid = (start + end) / 2;
mergeSortUp2Down(nums, start, mid, temp);
mergeSortUp2Down(nums, mid + 1, end, temp);
merge(nums, start, end, temp);
}
public static void merge(int[] nums, int start, int end, int[] temp) {
int mid = (start + end) / 2;
int left = start;
int right = mid + 1;
int index = start;
while (left <= mid && right <= end) {
if (nums[left] < nums[right]) {
temp[index++] = nums[left++];
} else {
temp[index++] = nums[right++];
}
}
while (left <= mid) {
temp[index++] = nums[left++];
}
while (right <= end) {
temp[index++] = nums[right++];
}
for (int i = start; i <= end; i++) {
nums[i] = temp[i];
}
}
public static void main(String[] args) {
int i;
int[] a = {80,30,60,40,20,10,50,70};
System.out.printf("before sort:");
for (i=0; i<a.length; i++) {
System.out.printf("%d ", a[i]);
}
System.out.printf("\n");
int[] temp = new int[a.length];
mergeSortUp2Down(a, 0, a.length-1, temp); // 归并排序(从上往下)
System.out.printf("after sort:");
for (i=0; i<a.length; i++) {
System.out.printf("%d ", a[i]);
}
System.out.printf("\n");
}
}