排序算法之--快速排序(及優化測試億級100_000_000用時)


該方法的基本思想是:

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM