归并排序(自顶向下) java版本

本文详细介绍了Java实现归并排序算法的过程,包括辅助数组的使用、分治法的应用及原地归并的实现。从算法原理到具体代码实现,全面解析归并排序的精妙之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

该算法思路如下:

1、新开辟一个辅助数组,方便归并时使用,由于归并时需要辅助空间,又防止在每次归并时都开辟一个新数组,所以提前申请一个同样大小空间的数组

2、将整个数组二分,分别递归排序前半部分与后半部分,之后将两部分归并

以上步骤二是分治法的典型思路

当我们的排序不断递归下去时,直到被拆分的数组中只有一个元素时,这时候数组便是有序的,之后和另一个相邻元素归并,。。直到前半部分有序,后半部分同样递归与归并,之后前半部分与后半部分归并,形成整个有序的一个数组。

归并的思路确实是相当精妙的。。。

以下为java版本的实现

public class merge_sort {
	//贵宾用的辅助数组
	private static int[] aux;
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] intarry={0,12,1,90,2,11,9,4,6,13,5,3,33};
		aux = new int[intarry.length];
		mergesort(intarry,0,intarry.length-1);
		for(int i:intarry){
			System.out.print(i);
			System.out.print(",");
		}
	}
	
	public static void mergesort(int[] intarry,int low,int high){
		if(high==low) return;
		int mid=low+(high-low)/2;
		mergesort(intarry,low,mid);
		mergesort(intarry,mid+1,high);
		merge(intarry,low,mid,high);
	}
	/***
	 * 原地归并
	 * @param intarrya 数组
	 * @param low 归并头节点
	 * @param mid 归并的分割点
	 * @param high 归并的尾节点
	 * 
	 */
	public static void merge(int[] intarry,int low,int mid,int high){
		int i=low;
		int j=mid+1;
		for(int k=low;k<=high;k++){
			aux[k]=intarry[k];
		}
		for(int k=low;k<=high;k++){
			if(i>mid){
				intarry[k] = aux[j++];
			}else if(j>high){
				intarry[k] = aux[i++];
			}else if(aux[i]<aux[j]){
				intarry[k]=aux[i++];
			}else{
				intarry[k]=aux[j++];
			}
		}
	}

}
其实归并的实现还有一种自底向上的实现与自顶向下的区别如下

自顶向下:

乱序5,4,2,1,6,3>>4,5,2,1,6,3>>4,5,1,2,6,3>>1,2,4,5,6,3>>1,2,4,5,3,6>>1,2,3,4,5,6

自底向上

乱序5,4,2,1,6,3>>4,5,2,1,6,3>>4,5,1,2,6,3>>4,5,1,2,3,6>>1,2,4,5,3,6>>1,2,3,4,5,6

自顶向下二路归并排序是一种利用分治策略的排序算法,它通过将数组分为两个相等或接近相等的部分,然后递归地对每个部分进行排序,最后合并这两个有序的部分得到整个数组的有序序列。以下是使用 Java 实现的简单版本: ```java public class MergeSort { // 分治函数,传入待排序数组的起始和结束索引 public static void mergeSort(int[] arr, int left, int right) { if (left < right) { // 找到中间位置 int mid = (left + right) / 2; // 递归对左半部分和右半部分进行排序 mergeSort(arr, left, mid); mergeSort(arr, mid + 1, right); // 合并左右两个已排序的部分 merge(arr, left, mid, right); } } // 合并两个已排序的部分 private static void merge(int[] arr, int left, int mid, int right) { int n1 = mid - left + 1; int n2 = right - mid; // 创建临时数组存储结果 int[] temp = new int[n1 + n2]; int i = 0, j = 0, k = 0; // 比较左边、右边部分的元素并按顺序放入临时数组 while (i < n1 && j < n2) { if (arr[left + i] <= arr[mid + 1 + j]) { temp[k++] = arr[left + i++]; } else { temp[k++] = arr[mid + 1 + j++]; } } // 将剩余未比较的元素复制到临时数组 while (i < n1) { temp[k++] = arr[left + i++]; } while (j < n2) { temp[k++] = arr[mid + 1 + j++]; } // 将临时数组的内容回填到原数组 for (i = left; i <= right; i++) { arr[i] = temp[i - left]; } } // 示例使用 public static void main(String[] args) { int[] arr = {9, 7, 5, 11, 12, 2, 14, 3}; int arrayLength = arr.length; mergeSort(arr, 0, arrayLength - 1); System.out.println("Sorted array: "); for (int num : arr) { System.out.print(num + " "); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值