众所周知,归并排序的时间复杂度是O(N*lgN)
归并排序的时间复杂度推导书上网上一抓一把,但是多数证明都是基于N=2k这个假设来证明的,下面我给出一般情况的证明。
先上归并排序代码:
public class MergeSort implements Sort { private static int count = 0; @Override public int[] sort(int[] data) { return sort(data, 0, data.length - 1); } private int[] sort(int[] data, int low, int high) { if (low == high) { return new int[] { data[low] }; } int mid = (low + high) >> 1; int[] left = sort(data, low, mid); //(1) int[] right = sort(data, mid + 1, high); //(2) int[] result = new int[high - low + 1]; int i = 0, k = 0;
//(3) for (int j = 0; j < result.length; j++) { count++; if (i == left.length) { result[j] = right[k++]; } else if (k == right.length) { result[j] = left[i++]; } else { if (left[i] <= right[k]) { result[j] = left[i++]; } else { result[j] = right[k++]; } } } return result; } }
根据代码可以看出,时间消耗主要在我标红的3个地方,可以得出:
我们知道每一个整数都可以表示为2i+k的形式,如1=20+0,5=22+1,10=23+2,因此
设N=2i+k
令n=i+1,则有:
根据我们对i和k的定义,k<2i(不然如果k>=2i那么i就应该能取到i+1了)。
因此有:
所以有:
回到开头的公式:
所以:
据此可以得出归并排序的时间复杂度是O(N*lgN)。