排序算法之归并排序

“归并”是将两个或两个以上的有序表组合成一个新的有序表。假定待排序表含有n个记录,则可以看成是n个

有序的子表,每个子表的长度为1,然后两两归并,得到n/2个长度为12或1的有序表;再两两归并,...如此重复,

直到合并成一个长度为n的有序表为止。这种排序方法称为2-路归并排序。

归并排序: (基于分治法)

	public void mergeSort(int[] a, int left, int right)
	{
		if (left < right)  // 至少有两个元素
		{
			int middle = (left + right) / 2; // 从中间划分出两个子序列
			mergeSort(a, left, middle); // 对左侧子序列进行递归排序
			mergeSort(a, middle+1, right); // 对右侧子序列进行递归排序
			merge(a, left, middle, right); // 将左右两个子序列合并
		}
	}

	private void merge(int[] a, int left, int middle, int right)
	{
		int[] tmpArray = new int[a.length]; // 创建一个临时数组,存放合并的数组
		int rightStart = middle + 1;
		int tmp = left;
		int third = left; // 合并后新数组的起始下标
		// 比较两个数组( [left,middle]和[middle+1, right] )中相应下标位置的元素大小,小的元素先放入新数组
		while (left <= middle && rightStart <= right)
		{
			if (a[left] <= a[rightStart])
			{
				tmpArray[third++] = a[left++];
			}
			else
			{
				tmpArray[third++] = a[rightStart++];
			}
		}
		// 如果左边数组还有元素,就把剩余的元素拷贝到新数组中
		while (left <= middle)
		{
			tmpArray[third++] = a[left++];
		}
		
		// 如果右边数组还有元素,就把剩余的元素拷贝到新数组中
		while (rightStart <= right)
		{
			tmpArray[third++] = a[rightStart++];
		}
		
		System.out.println("临时数组tmpArray:" + Arrays.toString(tmpArray));
		
		while (tmp <= right)
		{
			a[tmp] = tmpArray[tmp]; // 拷贝合并后的数组到原数组中
			tmp++;
		}
	}
	

2-路归并排序算法:

空间效率:merge()操作中,辅助空间的大小为n,所以空间复杂度为O(n)。

时间效率:每一趟归并排序的时间复杂度是O(n),共需要进行log2n归并,时间复杂度为O(nlog2n)。

稳定性:2-路归并排序算法是一个稳定的排序算法。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页