Quick Sort

 Quick sort is empirically fastest among all the O(nlogn) sorting algorithms.

 Time Complexity:

Best, Average, T(n) = 2T(n/2) + O(n) => O(nlogn)

Worst case (e.g. a sorted array) T(n) = T(n-1) + O(n)  =>O(n^2)

Space Complexity(From wiki).

Quicksort with in-place and unstable partitioning uses only constant additional space before making any recursive call. Quicksort must store a constant amount of information for each nested recursive call. Since the best case makes at most O(log n) nested recursive calls, it uses O(log n) space. However, without Sedgewick's trick to limit the recursive calls, in the worst case quicksort could make O(n) nested recursive calls and need O(n) auxiliary space.

 

public static void main(String[] args)
        {
            Random r = new Random();        
            int[] a = new int[]{r.nextInt(100), r.nextInt(100), r.nextInt(100),r.nextInt(100),r.nextInt(100),r.nextInt(100),r.nextInt(100),r.nextInt(100),r.nextInt(100),r.nextInt(100),r.nextInt(100)};
            System.out.println(Arrays.toString(a));        

            int[] aCopy = Arrays.copyOf(a, a.length);
            quickSort(aCopy);        
            System.out.println(Arrays.toString(aCopy));        
        }
        
        private static void quickSort(int[] a)
        {                
            quickSort(a, 0, a.length);
        }
        
        /**
         * @param [iBegin, iEnd)
         */
        private static void quickSort(int[] a, int iBegin, int iEnd)
        {                
            if(iEnd-iBegin<2)
                return;            
            /*
                Pivot selection can be improved by using a random values.
                If in that case, the pivot should be initially swapped to the end of this array.         
                Here I simply choose the last element of the array as the pivot.
               */
            int iPartition = getPartition(a, iBegin, iEnd);
            
            quickSort(a, iBegin, iPartition);
            quickSort(a, iPartition+1, iEnd);        
        }

        /**
         * This method assumes that the last element is the pivot value.
         * @param [iBegin, iEnd)
         * @return Return value is the index of the pivot after swap.
         */
        private static int getPartition(int[] a, int iBegin, int iEnd)
        {        
            int iPivot = iEnd - 1;
            int pivot = a[iPivot];        
            int iLeft = iBegin;
            int iRight = iPivot;
            while(true)
            {        
                //Move iLeft to the first value that's larger than pivot.
                //Or it stops at iRight
                while(iLeft<iRight && a[iLeft]<=pivot) ++iLeft;
                //Move iRight to the first value that's less than pivot.
                //Or it stops at iLeft
                while(iRight>iLeft && a[iRight]>=pivot) --iRight;            
                
                //If they meet, current place is where the pivot should be swapped to. 
                //And current place is guaranteed to have a value >= pivot
                //because left cursor moves before the right cursor.
                if(iLeft == iRight)
                {
                    a[iPivot] = a[iLeft];
                    a[iLeft] = pivot;
                    return iLeft;
                }
                
                //Only swap two numbers, no extra pointer movements 
                int temp = a[iRight];
                a[iRight] = a[iLeft];    
                a[iLeft] = temp;       
            }
        }

 

posted @ 2014-12-28 03:51  新一代的天皇巨星  阅读(180)  评论(0编辑  收藏  举报