java 排序--冒泡排序,选择排序,归并排序 快速排序。

冒泡排序:冒泡排序很简单,就是想冒泡一样,让小的数或者大的数往上“冒泡”。(这个大多数人应该都会了,就不在多啰嗦了!)注意!冒泡排序之后,不改变相同数的相对位置不会改变,所以冒泡排序还是有一定的稳定性的。

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a[]= {3,5,8,2,0,5,6};
		 M_sort(a);
		System.out.println("冒泡排序后:");
		for(int x:a) {
			System.out.print(x+" ");
		}

	}
	public static void M_sort(int a[]) {//其时间复杂度为O(n^2)
		for(int i=0;i<a.length-1;i++) {
			for(int j=0;j<a.length-i-1;j++)
				if(a[j]>a[j+1])
					merg(a,j,j+1);
		}
	}
	public static void merg(int a[],int m,int n) {
		int tem=a[m];
		a[m]=a[n];
		a[n]=tem;
	}

接下来是选择排序,这个的实现过程就是,找到未进行排序中的一个最小值,然后让这个最小值与

未排序的第一个值作交换,一直重复这个过程,直至让这个数组有序。

	public static void main(String[] args) {
		// TODO Auto-generated method stub
			int a[]= {3,5,8,2,0,5,6};
			 X_sort(a);
			System.out.println("选择排序后:");
			for(int x:a) {
				System.out.print(x+" ");
			}

		}
		public static void X_sort(int a[]) {
			for(int i=0;i<a.length;i++) {
				int tem=i;
				for(int j=i+1;j<a.length;j++) {
					if(a[j]<a[tem])
						tem=j;
				}
				merg(a,tem,i);
			}
		}
		public static void merg(int a[],int m,int n) {
			int tem=a[m];
			a[m]=a[n];
			a[n]=tem;
		}

归并排序感觉就比较难一点了,该过程利用递归

 

你可以把递归的过程看做一个黑盒,就是在划分左右的时候,已经对left-mid和mid+1-right位置排好序了(假设是这两个递归完成的这个操作(便于理解才有的这样的假设,实际过程比较复杂)) ,排的顺序如果是增的则两边都为增,如果为减两边都为减。这个时候,你只需要开辟一个辅助数组help,和两个“指针”p1=l,p2=m+1.比较p1和p2谁小,然后将这个小的数放到help数组里,然后将小的这一边向右移动一个位置,直至p1走到m,或者p2走到了r,这个时候,你只需要将剩下一个未走到头的值全部付给help数组就行,然后再把help数组的值传给目标数组。


	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int c[]= {3,5,8,2,0,5,6};
		G_sort(c,0,c.length-1);
		System.out.println("归并排序后:");
		for(int x:c) {
			System.out.print(x+" ");
		}
	}
	public static void G_sort(int a[],int left,int right) {//归并排序,其时间复杂度为O(n*logn)
		if(left==right)
			return ;
		int mid=left+(right-left)/2;
		G_sort(a,left,mid);
		G_sort(a,mid+1,right);//这就相当于是一个黑盒,你可以理解为,以mid为分界线(这个黑盒将mid左右的数排好序)。
		mark(a,left,mid,right);
		
	}
	public static void mark(int a[],int l,int m,int r) {
		int help[]=new int[r-l+1];
		int p1=l;
		int p2=m+1;
		int i=0;
		while(p1<=m&&p2<=r) {
			help[i++]=a[p1]>a[p2]?a[p2++]:a[p1++];
		}
		while(p1<=m)
			help[i++]=a[p1++];
		while(p2<=r)
			help[i++]=a[p2++];
		for(int j=0;j<help.length;j++) {
			a[l+j]=help[j];
		}
	}

 

 

快速排序有好几个版本,今天我们就写一下时间复杂度最低的一个版本。所谓的快速排序,就是以一个数为指标,将大于这个数的所有数放到最右边,小于这个数的数放到最左边,将等于这个数的数放到最中间。那该怎样实现这个过程呢?首先随机生成一个数,其范围在begin-endl之间,将这个位置上的数与endl位置上的数作交换,然后以endl为指标,(还需要定义边界,就是小于指标的数边界left=begin-1(数组最左),大于这个数的边界right=endl()数组最右)从begin开始,如果说begin位置上的数小于指标a[endl],那么让左边界边界加1,然后让左边界上的数与begin交换,然后begin加1;如果begin位置上的数与指标a[endl]上的数相等,只让begin加1就行;如果说begin位置上的数大于指标a[endl],让后让右边界减1,再让begin上的数与右边界上的数加1即可(千万不能让begin加1,因为交换之后begin上的数是一个新的数字,这个数字还未与指标比较过)。接下来上代码。

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int d[]= {3,5,8,2,0,5,6};
		K_sort(d,0,d.length-1);
		System.out.println("快速排序后:");
		for(int x:d) {
			System.out.print(x+" ");
		}
	}
	public static void K_sort(int a[],int begin,int endl) {//快速排序的其中一个版本,其时间复杂度为O(n*logn)
		if(endl>begin) {
			merg(a,begin+(int)(Math.random()*(endl-begin+1)),endl);
			int b[]=partition(a,begin,endl);
			K_sort(a,begin,b[0]-1);
			K_sort(a,b[1]+1,endl);
		}
	}
	public static int[] partition(int a[],int L,int R) {
		int left=L-1;
		int right=R;
		while(L<right) {
			if(a[L]>a[R])
				merg(a,L,--right);
			else if(a[L]==a[R])
				L++;
			else
				merg(a,L++,++left);
		}
		merg(a,right,R);
		return new int[]{left+1,right};
	}
	public static void merg(int a[],int m,int n) {
		int tem=a[m];
		a[m]=a[n];
		a[n]=tem;
	}

 后两个用的递归,不了解递归的可能感觉后两个排序不是很容易理解。

下一篇   二叉树排序和堆排序。

 

写此篇用于自律,以后会定期更新数据结构和算法,谢谢观看!

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小魏苦练算法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值