該方法的基本思想是:
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用時:
哈哈 感覺好神奇
https://www.cnblogs.com/MOBIN/p/4681369.html
https://blog.csdn.net/morewindows/article/details/6684558