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

来源:互联网 发布:网络黑侠现在在哪写书 编辑:程序博客网 时间:2024/05/27 00:58

合并排序:

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++];elsetempArr[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+" ");}}
运行结果:



1 0