(四)合并排序

一)问题描述:
   对n个元素进行排序。
二)基本思路:
  将待排序的n个元素先从中间,即n/2的位置进行分解(如果是奇数,可以考虑将多出来的元素放入前半部分或者后半部分,一旦确定是前半部分或者后半部分,则要求以后的操作均以这一次为标准,都放入前半部分或后半部分),一直分解到单个元素为一个组,之后两两拼合。

分解:分解顺序,不同颜色的线条表示不同次数的分解结果
合并:

合并的顺序
三)代码
  主函数:

//主函数
public  static void main(String[] args) {
		MergeSort k=new MergeSort();
		k.mergeSort();
		System.out.println(k);
	}

  因为,虽然要分解,但是都是分解到最后一个元素,所以,可以直接两两合并,不进行递归的分解。


//类,及其初始化
public class MergeSort {
	int[] a;
	int[] b;
	int n;
	int left;
	int right;

	public MergeSort() {
		this.initialize();
	}
	@SuppressWarnings("resource")
	public void initialize() {
		System.out.println("please enter the number you want to sort:");
		Scanner number=new Scanner(System.in);
		this.n=number.nextInt();
		if(n<2)
		{
			return ;
		}
		//初始化数组
		a=new int[n];
		b=new int[n];
		for(int i=0;i<n;i++)
		{
			a[i]=0;
			b[i]=0;
		}
		//正式赋值
		System.out.println("please enter the number:");
		for(int i=0;i<n;i++)
		{
			Scanner c=new Scanner(System.in);
			this.a[i]=c.nextInt();
		}
	}

说明:mergeSort():将已有a[] 按照s个元素进行依次合并;

public void mergeSort() {
		int s=1;
		while(s<n) {//当s<n时,进行分解
			this.mergePass(s);//统一放在x中
			s+=s;
		}
	}

说明:mergePass():将a[]按照s分解,更新;

public void mergePass(int s) {
		int i=0;
		while(i<n-2*s) {//比如n=5;第一次就是i<3即前三个,也就是会留下剩下的3、4为一组,之前的为一组
			merge(i,i+s-1,i+2*s-1);
			i=i+2*s;
		}
		if(i+s<n){merge(i,i+s-1,n-1);}
		else {
			for(int j=i;j<=n-1;j++) {b[j]=a[j];}
		}
		for(int k=0;k<n;k++)
		{a[k]=b[k];//这里相当重要,因为是都在一个数组上面操作,所以需要每次都更新数组a}
	}

说明:merge():将数组分开的部分进行合并

public void merge(int f,int m,int e) {
		int i=f;
		int j=m+1;
		int k=f;
		while((i<=m)&&(j<=e))
		{
			if(a[i]<=a[j]) {b[k++]=a[i++];}
			else {b[k++]=a[j++];}
		}
		//将刚才没有添进去的元素添进去;
		if(i>m)//时第一部分没有添加完毕,所以将第二部分添加进去;
		{
			for(int q=j;q<=e;q++)
			{	b[k++]=a[q];}
		}
		if(j>e)
		 {
			for(int q=i;q<=m;q++)
			{	b[k++]=a[q];}
		}
	}

说明:输出

public String toString() {
		for(int i=0;i<n;i++)
		{System.out.print(b[i]+" ");}
		return "";
	}

结果:
运行结果

时间复杂度:
O(n logn)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值