java实现归并排序

思路:将两个或两个以上的有序序列合并成一个有序序列

代码如下:

public class MergeS {
	private static void merge(int r[],int r1[],int s,int m,int t){
		int i=s,j=m+1,k=s;
		while(i<=m&&j<=t){
			if(r[i]<=r[j]){
				r1[k++]=r[i++];       //取r[i]和r[j]中较小者放入r1[k]
			}
			else{
				r1[k++]=r[j++];
			}
		}
		if(i<=m){
			while(i<=m){              //若第一个子序列处理完,则进行收尾处理
				r1[k++]=r[i++];
			}
		}
		else{
			while(j<=t){              //若第二个子序列处理完,则进行收尾处理
				r1[k++]=r[j++];
			}
		}
	}
	private static void mergePass(int r[],int r1[],int n,int h){
		int i=0;
		while(i<=n-2*h){              //待归并记录至少有两个长度为h的子序列
			merge(r,r1,i,i+h-1,i+2*h-1);
			i+=2*h;
		}
		if(i<n-h){
			merge(r,r1,i,i+h-1,n);    //待归并序列中有一个长度小于h
		}
		else{
			for(int k=i;k<=n;k++){    //待归并序列中只剩一个子序列
				r1[k]=r[k];
			}
		}
	}
	public static void mergeS(int r[],int r1[],int n){
		int h=1;
		while(h<n){
			mergePass(r,r1,n-1,h);
			h=2*h;
			mergePass(r1,r,n-1,h);
			h=2*h;
		}
	}
	public static void main(String[] args) {
		int r[]={36,45,12,56};
		int r1[]=new int[4];
		System.out.println("原始数列是:");
		for(int i=0;i<r.length;i++){
			System.out.print("  "+r[i]);
		}
		mergeS(r,r1,r.length);
		//mergePass(r,r1,r.length-1,1);
		System.out.println("\n"+"新数列是:");
		for(int i=0;i<r.length;i++){
			System.out.print("  "+r[i]);
		}
	}

}

运行结果:

<think>好的,我现在需要帮助用户找到Java实现归并排序的代码或教程。首先,我需要回忆归并排序的基本原理和步骤。归并排序是分治法的一个典型应用,分为分解和合并两个阶段。分解阶段将数组分成两半,递归地对子数组进行排序,然后合并已排序的子数组。 用户提供的引用中有几个关于Java实现归并排序的内容。引用[3]详细说明了归并排序的步骤:分解、解决、合并。引用[5]提到了merge方法中使用三个指针来比较和合并子数组。引用[2]提供了一个测试代码示例,但主要是归并排序后的测试部分,可能不够完整。引用[4]分析了归并排序的时间复杂度为O(N log N),这对于用户理解算法效率有帮助。 接下来,我需要整合这些信息,提供一个结构清晰的Java实现示例。首先,分解部分需要递归地将数组分成两半,直到子数组长度为1。合并部分需要将两个有序数组合并一个。引用[5]中的merge方法使用临时数组和三个指针,这部分需要详细说明。 需要注意的是,代码的正确性。例如,在合并过程中,需要处理剩余元素的情况,避免遗漏。引用[2]的测试代码可以作为验证示例,确保排序正确。 用户可能需要了解优化方法,比如在小数组时使用插入排序,或者减少临时数组的创建次数。引用[1]提到了归并排序的优化,但具体内容未详细展开,可能需要简要提及。 最后,确保回答符合格式要求:使用中文,代码块正确,引用标识自然添加。同时生成相关问题,帮助用户进一步学习。</think>### Java实现归并排序算法详解 归并排序是一种基于**分治法**的稳定排序算法,其核心思想是将待排序序列递归地分解为若干子序列,分别排序后再合并。以下是分步实现说明及完整代码: --- #### 1. 算法原理 1. **分解**:将长度为$n$的序列分成两个长度为$n/2$的子序列。 2. **递归排序**:对左右子序列递归执行归并排序。 3. **合并**:将两个有序序列合并一个有序序列[^3][^4]。 --- #### 2. Java代码实现 ```java public class MergeSort { public static void mergeSort(int[] arr) { if (arr == null || arr.length <= 1) return; int[] temp = new int[arr.length]; // 临时数组避免频繁内存分配 sort(arr, 0, arr.length - 1, temp); } private static void sort(int[] arr, int left, int right, int[] temp) { if (left < right) { int mid = left + (right - left) / 2; sort(arr, left, mid, temp); // 递归排序左半部分 sort(arr, mid + 1, right, temp); // 递归排序右半部分 merge(arr, left, mid, right, temp); // 合并有序子数组 } } private static void merge(int[] arr, int left, int mid, int right, int[] temp) { int i = left; // 左子数组起始指针 int j = mid + 1; // 右子数组起始指针 int 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++]; // 将临时数组复制回原数组 System.arraycopy(temp, 0, arr, left, k); } public static void main(String[] args) { int[] arr = {10, 9, 34, 59, 30, 100, 3, 10, 45, 25}; mergeSort(arr); System.out.println(Arrays.toString(arr)); // 输出:[3, 9, 10, 10, 25, 30, 34, 45, 59, 100][^2] } } ``` --- #### 3. 关键点说明 - **时间复杂度**:始终为$O(n \log n)$,适合大规模数据排序[^4]。 - **空间复杂度**:$O(n)$,主要来自临时数组的使用。 - **稳定性**:合并时判断`arr[i] <= arr[j]`保证相等元素的顺序不变。 --- #### 4. 优化建议 1. **小数组优化**:当子数组长度较小时(如≤15),改用插入排序减少递归开销[^1]。 2. **减少复制操作**:交替使用原数组和临时数组,避免频繁复制。 3. **提前终止合并**:若左子数组最大值≤右子数组最小值,无需合并。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值