排序算法之归并排序

“归并”是将两个或两个以上的有序表组合成一个新的有序表。假定待排序表含有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-路归并排序算法是一个稳定的排序算法。

归并排序(Merge Sort)是一种稳定的、基于比较的排序算法,最坏时间复杂度为 O(nlogn)。其基本思想是将待排序序列分成若干个子序列,每个子序列都是有序的,然后将子序列合并成整体有序的序列。 归并排序的实现方法有两种:自顶向下和自底向上。 自顶向下的归并排序算法实现: 1. 将待排序序列分成两个子序列,分别对这两个子序列进行递归排序。 2. 将两个已经排好序的子序列合并为一个有序序列。 自底向上的归并排序算法实现: 1. 将待排序序列每个元素看成一个独立的有序序列,进行两两合并。 2. 得到 n/2 个长度为 2 的有序序列,再两两合并。 3. 重复步骤 2,直到得到一个长度为 n 的有序序列。 下面是自顶向下的归并排序算法的实现代码(使用了递归): ``` void MergeSort(int arr[], int left, int right) { if (left >= right) return; int mid = left + (right - left) / 2; MergeSort(arr, left, mid); MergeSort(arr, mid + 1, right); int* temp = new int[right - left + 1]; int i = left, j = mid + 1, k = 0; while (i <= mid && j <= right) { if (arr[i] <= arr[j]) temp[k++] = arr[i++]; else temp[k++] = arr[j++]; } while (i <= mid) temp[k++] = arr[i++]; while (j <= right) temp[k++] = arr[j++]; for (int p = 0; p < k; p++) arr[left + p] = temp[p]; delete[] temp; } ``` 下面是自底向上的归并排序算法的实现代码(使用了迭代): ``` void MergeSort(int arr[], int n) { int* temp = new int[n]; for (int len = 1; len < n; len *= 2) { for (int left = 0; left < n - len; left += len * 2) { int mid = left + len - 1; int right = min(left + len * 2 - 1, n - 1); int i = left, j = mid + 1, k = 0; while (i <= mid && j <= right) { if (arr[i] <= arr[j]) temp[k++] = arr[i++]; else temp[k++] = arr[j++]; } while (i <= mid) temp[k++] = arr[i++]; while (j <= right) temp[k++] = arr[j++]; for (int p = 0; p < k; p++) arr[left + p] = temp[p]; } } delete[] temp; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值