分治法之经典算法一--合并排序

最近打算把算法捋一捋,这次是分治法的典型例子:合并排序。需要的朋友请自取哦!欢迎大家和我一起交流~~

1.合并排序算法思想:
将待排序的有n个元素的序列分割成两个规模大小相同的子数组,如果子数组规模到达容易求出排序时停止分割,否则继续分割。直到容易求出排序也就是子数组只有单元素时,我们把它视为容易解决排序的问题规模,我们认为这个具有单元素的子数组已经排好序,然后将两两相邻的子数组合并成所要求的序列,直到不再存在未合并的子数组,算法终止。
步骤:
先将待排序列分割成子数组;
当子数组只有单个元素时停止分割;
将这些子数组两两合并。

2.代码如下:
‘’’
//分治法_合并排序;
public class MergeSort {

public static void MergeSort1(Comparable a[],int left,int right){
	Comparable []b =new Comparable[right+1];
	if(left<right) {//至少俩元素
		int i=(left+right)/2;//取中点
		MergeSort1(a,left,i);//处理左半段
		MergeSort1(a,i+1,right);//处理右半段
		Merge(a,b,left,i,right);//将两段序列合并成有序结果
		Copy(a,b,left,right);//复制
	}
}


//合并排序,把两段待排序序列合并成有序结果
 static void Merge(Comparable [ ] c, Comparable  d[ ] ,int l, int m , int r) {
	
		int i=l;//第一段的游标(起始位置)
		int j=m+1;//第二段的游标(起始位置)
		int k=l;//结果的游标
		//只要段里面存在i和j,不断进行归并
		while((i<=m)&&(j<=r)) {
			if(c[i].compareTo(c[j])<=0)
				d[k++]=c[i++];
			else d[k++]=c[j++];
		}
		//把余下部分加入到数组中
		if(i>m) {
			for(int q=j;q<=r;q++) 
				d[k++]=c[q];
			}
		else {
			for(int q=i;q<=m;q++)
				d[k++]=c[q];
		}
	
}
 //复制数组
  static void Copy(Comparable[] a, Comparable[] b, int left, int right) {
		for(int i=left;i<=right;i++) {
			a[i]=b[i];
		}
		
	}
public static void main(String[] args) {
	Comparable[] a= {23,5,9,16,30,25,17,18};
	MergeSort1(a,0,7);
	System.out.println("合并排序后结果:");
	for(int i=0;i<=7;i++) {
		System.out.print(a[i]+" ");
	}
	

}

}

‘’’

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
分治法是一种常用的算法设计方法,它将一个大问题分解成若干个相同或类似的子问题,然后递归地解决这些子问题,最后将子问题的解合并起来得到原问题的解。归并排序就是一种使用分治法的排序算法。 归并排序的思想如下: 1. 将待排序的数组不断地二分,直到每个子数组只有一个元素。 2. 将相邻的两个子数组进行合并,合并时按照从小到大的顺序将元素放入一个临时数组中。 3. 重复步骤2,直到所有的子数组都合并成一个有序的数组。 以下是C++实现归并排序算法的代码示例: ```cpp // 合并两个有序数组 void merge(vector<int>& nums, int left, int mid, int right) { vector<int> temp(right - left + 1); // 临时数组用于存放合并结果 int i = left; // 左子数组的起始位置 int j = mid + 1; // 右子数组的起始位置 int k = 0; // 临时数组的索引 // 将两个子数组中较小的元素依次放入临时数组中 while (i <= mid && j <= right) { if (nums[i] <= nums[j]) { temp[k++] = nums[i++]; } else { temp[k++] = nums[j++]; } } // 将剩余的元素放入临时数组中 while (i <= mid) { temp[k++] = nums[i++]; } while (j <= right) { temp[k++] = nums[j++]; } // 将临时数组中的元素复制回原数组 for (int m = 0; m < k; m++) { nums[left + m] = temp[m]; } } // 归并排序 void mergeSort(vector<int>& nums, int left, int right) { if (left >= right) { return; } int mid = left + (right - left) / 2; mergeSort(nums, left, mid); // 对左子数组进行排序 mergeSort(nums, mid + 1, right); // 对右子数组进行排序 merge(nums, left, mid, right); // 合并两个有序子数组 } // 调用归并排序函数 vector<int> nums = {5, 2, 9, 1, 7}; mergeSort(nums, 0, nums.size() - 1); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值