标签:归并排序 java
思想:
假设初始序列右n个记录,首先将这n个记录看成n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2向上取整 个长度为2(n为奇数时,最后一个序列的长度为1)的有序子序列。在此基础上,在对长度为2的有序子序列进行两两归并,得到若干个长度为4的有序子序列。如此重复,直至得到一个长度为n的有序序列为止。
稳定性:稳定
时间复杂度计算:
数组的大小是2的幂,这样分下去始终可以被2整除。假设为2的k次方,即k=log2(n)。
每次我们选择的值刚好是中间值,这样,数组才可以被等分。
第一层递归,需要循环n次才能排序好,第二层循环2*(n/2)......
所以共有n+2(n/2)+4(n/4)+...+n*(n/n) = n+n+n+...+n=k*n=log2(n)*n
所以算法复杂度为O(log2(n)*n) 。
代码:
public static void sort(int[] data, int left, int right) {
System.out.println(left+":"+right);
if (left < right) {
int center = (left + right) / 2;
System.out.println(left+":"+center+":"+right);
// 对左边数组进行递归
sort(data, left, center);
System.out.println(left+":"+center+":"+right);
// 对右边数组进行递归
sort(data, center + 1, right);
// 合并
merge(data, left, center, right);
}
}
public static void merge(int[] data, int left, int center, int right) {
int[] tmpArr = new int[data.length];
int mid = center + 1;
// third记录中间数组的索引
int third = left;
int tmp = left;
while (left <= center && mid <= right) {
// 从两个数组中取出最小的放入中间数组
if (data[left] <= data[mid]) {
tmpArr[third++] = data[left++];
} else {
tmpArr[third++] = data[mid++];
}
}
// 剩余部分依次放入中间数组
while (mid <= right) {
tmpArr[third++] = data[mid++];
}
while (left <= center) {
tmpArr[third++] = data[left++];
}
// 将中间数组中的内容复制回原数组
while (tmp <= right) {
data[tmp] = tmpArr[tmp++];
}
System.out.println(Arrays.toString(data));
}
public static void main(String[] args) {
int[] a1 = {5,1,3,4,2};
sort(a1,0,a1.length-1);
}标签:归并排序 java
原文地址:http://7835295.blog.51cto.com/7825295/1640322