该方法的基本思想是:
1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。
挖坑填数+分治法:
对挖坑填数进行总结
1.i =L; j = R; 将基准数挖出形成第一个坑a[i]。
2.j--由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。
3.i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。
4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中。
第一版快排(数据100_000_00级的):
//1.先从数列中取出一个数作为基准数。 //2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。 //3.再对左右区间重复第二步,直到各区间只有一个数。 public static void Quicksort(int [] arr,int left,int right) { if(arr.length<=1 || arr==null) { return; } if(left<right) { int mid=getmid(arr,left,right); Quicksort(arr,left,mid-1); Quicksort(arr,mid+1,right); } } //1.i =L; j = R; 将基准数挖出形成第一个坑a[i]。 //2.j--由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。 //3.i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。 //4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中。 public static int getmid(int [] arr,int left,int right) { int temp=arr[left]; while (left<right) { //从右往左 //最左边小于第一个数 while (left<right && arr[right]>=temp) { right--; } //将最右边比基准数小的数移到左边 arr[left]=arr[right]; //从左往右 //最右边大于第一个数 while (left<right &&arr[left]<temp) { left++; } //将最左边比基准数大的移到右边 arr[right]=arr[left]; } arr[left]=temp;//基准元素归位 return left; } public static void main(String[]arg) { //int [] ints =new int[]{12 ,9 ,8 ,1,2,7 , 1 , 2 ,3 , 6 }; int[] ints=new int[100_000_00]; for(int i=0;i<ints.length;i++){//随机产生数据 ints[i]=(int)(Math.random()*1000+1); } System.out.println("程序运行时间:start" + "ms"); long startTime = System.currentTimeMillis(); //获取开始时间 //show(ints); Quicksort(ints,0,ints.length-1); //show(ints); long endTime = System.currentTimeMillis(); //获取结束时间 System.out.println("程序运行时间:" + (endTime - startTime) + "ms"); //输出程序运行时间 } public static void show(int [] ints) { for(int i=0;i<ints.length;i++) { System.out.print(ints[i]+" "); } System.out.println(""); }
用时:
如果把数据加成100_000_000亿级的,会出现栈溢出!!
分析:
第一版只是一般书上的快速排序,如果出现大量重复数据,在左右移动过程中就会浪费不少次数,所以,我们要在加一个变量限制。
第二版:
public static void swap( int [] arr, int low,int high) { int temp=arr[low]; arr[low]=arr[high]; arr[high]=temp;//数据交换 } public static void Qsortplus( int [] arr, int low,int high) { if(low < high) { int lt=low; int gt=high;//左边,右边 int i=low+1;//开始循环位置 int temp=arr[low];//保存第一个数据 while(i<=gt)//循环夹逼 { if(arr[i]<temp) //小于 { swap(arr, lt,i);//移动 lt++; i++; } else if(arr[i]>temp)//大于 { swap(arr,i,gt);//移动 gt--; } else { i++; } } Qsortplus( arr, low,lt-1); Qsortplus( arr, gt+1,high);//分段 } } public static void show(int[] args) { for(int i=0;i<args.length;i++) { System.out.print(args[i]+" "); } System.out.println(""); } public static void main(String[] args) { // int [] arr=new int[]{4,1,2,9,4,6,4,2,4,3,4,1,7,4,7,4,7,7}; int[] arr=new int[100_000_00]; for(int i=0;i<arr.length;i++){//随机产生数据 arr[i]=(int)(Math.random()*1000+1); } long startTime = System.currentTimeMillis(); //获取开始时间 Qsortplus( arr,0,arr.length-1); // show(arr) ; long endTime = System.currentTimeMillis(); //获取结束时间 System.out.println("程序运行时间:" + (endTime - startTime) + "ms"); //输出程序运行时间 }
用时:
测试亿级100_000_000用时:
哈哈 感觉好神奇