Java语言描述:递归与分治策略之合并排序与快速排序

合并排序:

package DivideAndConquer;

public class MergeSort {
	//一定要多传入一个多余的temp数组用于存放排序的中间结果
	public static<AnyType extends Comparable<? super AnyType>> 
		void mergeSort1( AnyType [] a,AnyType[] temp,int left,int right){
		//只要容器中的最左边的元素序号小于最右边的元素序号,递归就继续下去
		  if(left < right){
			int middle = (left+right)/2;
			mergeSort1(a,temp,left,middle);
			mergeSort1(a,temp,middle+1,right);
			merge1(a,temp,left,middle+1,right);
		}
	}
	//数组a为需要排序的原数组,temp为存放中间量的临时容器,left为需要合并的第一个容器的最左端
	//Right为需要合并的第二个容器的最左端,RightEnd为需要合并的第二个容器的最右端。
	public static<AnyType extends Comparable<? super AnyType>>
		void merge1(AnyType[] a,AnyType[] tempArr,int Left,int Right,int RightEnd){
		int leftEnd = Right - 1;
		int tempPos = Left;
		int numElements = RightEnd-Left+1;
		//有一个集合为空后,该循环停止
		while(Left<=leftEnd && Right<=RightEnd){
			if(a[Left].compareTo(a[Right])<=0)
				tempArr[tempPos++] = a[Left++];
			else
				tempArr[tempPos++] = a[Right++];
		}
		//将剩下的元素全部放入临时容器
		while(Left<=leftEnd)
			tempArr[tempPos++] = a[Left++];
		while(Right<=RightEnd)
			tempArr[tempPos++] = a[Right++];
		for(int i=0;i<numElements;RightEnd--,i++)
			a[RightEnd] = tempArr[RightEnd];
	}

	public static void main(String[] args){
		Integer[] test = {4,6,9,1,0,3,5,6,1};
		Integer[] temp = new Integer[test.length];
		System.out.print("原先的顺序为:");
		for(int s : test)
			System.out.print(s+" ");
		System.out.println();
		System.out.print("排序后的顺序为:");
		mergeSort1(test,temp,0,test.length-1);
		for(int s : test)
			System.out.print(s+" ");
	}
}
运行结果:


快速排序:

/*
 * 本代码实现了可比较对象集合的快速排序。选取枢纽元的方法为通过完全随机化的方法产生。
 * 这种方法存在一定的不科学性,因为产生随机数本身会花费较多的时间,也可以通过三值中值法来
 * 产生枢纽元。产生枢纽元后,将枢纽元和集合第一个位置上的元素互换,放到首位来,然后通过两个指针,
 * 第一个从集合第二个位置出发(第一个位置是枢纽元),当元素小于枢纽元时,指针向后移动。第二个
 * 从集合的最后一个位置出发,当元素大于枢纽元时,指针向前移动。当2个指针都停止时,且第一个指针的
 * 位置依然在第二个指针的位置的左边时,将这2个元素互换,然后继续走下去,直到2个指针都停止,且第一个
 * 指针跑到了第二个指针的右边或重合。要注意,第2个指针肯定是不会越界的(因为队首有枢纽元作守卫),
 * 但是第1个指针有可能会越界(当后半部分的值全部小于枢纽元的时候),因此要在第一个指针的地方多加
 * 一层判断,确保不会越出数组。
 * */
package DivideAndConquer;

import java.util.Random;

public class QuickSort {
		//采用分治法递归调用快速排序方法,直到某个区间内就剩一个元素。
		public static<AnyType extends Comparable<? super AnyType>> 
			void quickSort(AnyType [] a,int left,int right){
			if(left<right){
			int random = partition(a,left,right);
			quickSort(a,left,random-1);
			quickSort(a,random+1,right);
			}
		}
		
		public static<AnyType extends Comparable<? super AnyType>> 
		int partition(AnyType [] a,int left,int right){
			Random r = new Random();
			//产生left到right(包含)之间的随机数作为枢纽元,并放置到队首
			int ran = left + r.nextInt(right-left+1);
			swap(a,left,ran);
			int leftPos = left;//左边的指针,马上++后从Left+1号元素开始
			int rightPos = right+1;//右边的指针,马上--后从right号元素开始
			while(true){
				while(a[++leftPos].compareTo(a[left])<0 && leftPos < right);//多一个判断条件
				while(a[--rightPos].compareTo(a[left])>0);//有枢纽元守门,不怕越界
				if(leftPos < rightPos) swap(a,leftPos,rightPos);
				else break;
			}
			swap(a,left,rightPos);		//注意一定要将右边过来的指针和枢纽元换位置后返回,才不会死循环。
			return rightPos;		
		}
		public static<AnyType extends Comparable<? super AnyType>> 
		void swap(AnyType [] a,int m,int n){
			AnyType temp = a[m];
			a[m] = a[n];
			a[n] = temp;
		}
		public static void main(String[] args){
			Integer[] test = {4,6,9,1,0,3,5,6,1};
			System.out.print("原先的顺序为:");
			for(int s : test)
				System.out.print(s+" ");
			System.out.println();
			System.out.print("排序后的顺序为:");
			quickSort(test,0,test.length-1);
			for(int s : test)
				System.out.print(s+" ");
		}
}
运行结果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值