Docstoc

Quick Sort

Document Sample
Quick Sort Powered By Docstoc
					                     Quick Sorting
                     (Chapter 11)




                      Quick Sort
So far, we have learned quite a few algorithms for sorting:
Bubble sort, selection sort, insertion sort and merge sort.

Here, we are going to learn yet another algorithm for sorting
objects.




                                                                1
Recall that in merge sort, we use an approach called divide-
and-conquer. This approach is also used in quick sort. Suppose
we have a sequence S.

 1. Divide: If S has at least two elements (nothing needs to be
    done if S has zero or one element), select a specific
    element x from S, which is called the pivot. As is common
    practice, choose the pivot x to be the last element in S.
    Remove all the elements from S and put them into three
    sequences:
    1) L, storing the elements in S less than x
    2) E, storing the elements in S equal to x
    3) G, storing the elements in S greater than x.
    Of course, if the elements of S are all distinct, then E holds
    just one element - the pivot itself.




  2. Recur: Recursively sort sequence L and G.
  3. Conquer: Put back the elements into S in order by first
     inserting the elements of L, then those of E, and finally
     those of G.
Example:

We have a sequence (85, 24, 63, 45, 17, 31, 96, 50). It is
difficult to sort in one step. So we pick the number 50 (pivot)
and divide elements into three sequences: (24, 45, 17, 31), (50),
and (85, 63, 96). Now the problem becomes that we need to
sort these three sequences. However, they are smaller and
hopefully easier to sort.




                                                                     2
Now we take the first sequence (24, 45, 17, 31) and see that
it is still too complicated to sort in one step. So we pick the
number 31 as a pivot and split the sequence further into
three sequences (24, 17), (31), and (45). Now two
sequences (31) and (45) are easy enough to sort (they are
trivially sorted.)

The sequence (24, 17), however, is still complicated.
Again, we pick the number 17 as a pivot and split the
sequence into three sequences (), (17), and (24). Now all
these smaller sequences are sorted.

We now need to put them together. The result is (17, 24).
Next, we put sequences (17, 24), (31), and (45) together.
The result is (17, 24, 31, 45).




Similarly, the sequence (85, 63, 96) will be sorted.
The result is
   (63, 85, 96).

So we put the sequences (17, 24, 31, 45), (50) and (63, 85, 96)
together to have a sorted sequence:

    (17, 24, 31, 45, 50, 63, 85, 96).




                                                                  3
   The figure here shows how the sequence is divided into smaller
   sequences and pivots.

               85 24 63 45 17 31 96 50


            24 45 17 31             85 63 96


           24 17        45         85 63


             24                        85




       The figure here shows how the sequences merged.

                    17 24 31 45 50 63 85 96

               17 24 31 45            63 85 96        pivot 50


pivot 31      17 24          45      63 85             pivot 96


                   24   pivot 17            85   pivot 63




                                                                    4
In-Place Quick Sort

in-place: Use only a constant amount of memory space in
additional to the sequence itself. Instead of transfering
elements in and out of a memory block, we simply rearrange
them.

Recall that in the step of divide-and-conquer, we split the
sequence into three groups: a pivot, a sequence containing
elements less then the pivot, and a sequence containing
elements greater than the pivot.

Let us see how this is done by rearranging the elements within
the sequence.




What do we want: The two smaller sequences are
separated by the pivot.
For example:
     31 24 17 45 50 85 96 63
How can we do it: Using two indices, starting from
both ends. We search for a pair of elements such that
one is smaller than the pivot and the other is larger than
the pivot. Then, swap them. We repeat this process
until the two indices meet.
     85 24 63 45 17 31 96 50
 l                        r




                                                                 5
Algorithm inPlaceQuickSort(S, a, b)
   Input: Sequence S of elements; integers a and b
   Output: Sequence S with elements originally from ranks
       from a to b, inclusive, sorted in nondecreasing order
       from ranks a to b
   if a is greater than or equal to b
        return
   assign the element at rank b to variable p (pivot)
   assign a to variable l
   assign b - 1 to variable r
   while l is less than or equal to r
        while l is less than or equal to r and
            the element at rank l is less than or equal to p
            increase l by 1




     while r is greater than or equal to l and
          the element at rank r is greater than or equal to p
          decrease r by 1
     if l is less than r
          swap the elements at ranks l and r
 swap the elements at ranks l and b
 inPlaceQuickSort(S, a, l - 1)
 inPlaceQuickSort(S, l + 1, b)




                                                                6
Example:


     85 24 63 45 17 31 96 50
 l                       r


     85 24 63 45 17 31 96 50
 l                   r

     31 24 63 45 17 85 96 50
 l                   r




      31 24 63 45 17 85 96 50
           l     r

      31 24 17 45 63 85 96 50
           l     r


      31 24 17 45 63 85 96 50
               r l

      31 24 17 45 50 85 96 63
               r l




                                7
    Java implementation
    public static void quickSort( Sequence S, Comparator c ) {
        if( S.size() < 2 )
            return;
        quickSortStep( S, c, 0, S.size() - 1 );
    }

    private static void quickSortStep( Sequence S, Comparator c,
        int leftBound, int rightBound ) {
        if( leftBound >= rightBound )
            return;
        Object pivot = S.atRank( rightBound ).element();
        int leftIndex = leftBound;
        int rightIndex = rightBound - 1;
        while(( leftIndex <= rightIndex ) {
            while(( leftIndex <= rightIndex ) &&
                c.isLessThanorEqualTo( S.atRank( leftIndex ).element(),
                    pivot ))
            leftIndex++;




          while((rightIndex >= leftIndex ) &&
              c.isGreaterThanorEqualTo(
                  S.atRank( rightIndex ).element(), pivot ))
              rightIndex--;
          if( leftIndex < rightIndex )
              S.swapElements( S.atRank( leftIndex ),
                  S.atRank( rightIndex ));
      }
      S.swapElements( S.atRank( leftIndex ),
          S.atRank( rightBound ));
      quickSortStep( S, c, leftBound, leftIndex - 1 );
      quickSortStep( S, c, leftBound + 1, rightBound );
}




                                                                          8
 The running time of quick sort is proportional to the square of n,
 the size of the sequence: O(n2).

 Average running time: O(nlogn).
 In practice, the quick sort works better than the merge sort.




Lab 9:
import java.lang.*;
public class QuickSorter {
  public static void quickSort (Integer[] S, Comparator c) {
    if (S.length < 2) return;
// the array is already sorted in this case
    quickSortStep(S, c, 0, S.length-1);
// recursive sort method
  }
  private static void quickSortStep (Object[] S, Comparator c,
                               int leftBound, int rightBound ) {
    if (leftBound >= rightBound) return;
// the indices have crossed
    Object temp;
// temp object used for swapping
    Object pivot = S[rightBound];
    int leftIndex = leftBound;      // will scan rightward
    int rightIndex = rightBound-1; // will scan leftward
    while (leftIndex <= rightIndex) {
// scan right until larger than the pivot
      while ( (leftIndex <= rightIndex) &&
       (c.compare(S[leftIndex], pivot)<=0) )
        leftIndex++;




                                                                      9
// scan leftward to find an element smaller than the pivot
while ( (rightIndex >= leftIndex) &&
              (c.compare(S[rightIndex], pivot)>=0))
        rightIndex--;
      if (leftIndex < rightIndex) {
       // both elements were found
        temp = S[rightIndex];
       S[rightIndex] = S[leftIndex]; // swap these elements
       S[leftIndex] = temp;
      }
    } // the loop continues until the indices cross
    temp = S[rightBound];
       // swap pivot with the element at leftIndex
    S[rightBound] = S[leftIndex];
    S[leftIndex] = temp;
       // the pivot is now at leftIndex, so recurse
    quickSortStep(S, c, leftBound, leftIndex-1);
    quickSortStep(S, c, leftIndex+1, rightBound);
  }




   public static void main (String[] args) {
         int k = 0;
         Integer[] nums = new Integer[10];
         System.out.println("Quick sorting:" + "\n");
         System.out.println("Input sequence:" + "\n");
         //Create an array to hold numbers
         for(int i = 0; i < nums.length; i++)
            {k = (int) (Math.random()*100);
         //Generate random numbers
              nums[i] = new Integer(k);
              System.out.print(k + " ");
            }
         System.out.println();




                                                              10
        System.out.println();
        System.out.println();
        Comparator c = new Comparator();

        quickSort(nums, c); //Sort them
        System.out.println("Result:" + "\n");
        for (int j = 0; j < nums.length; j++) //Print them out
            System.out.print(nums[j].intValue() + " ");
        System.out.println();
    }

}




                                                                 11

				
DOCUMENT INFO
Shared By:
Categories:
Stats:
views:11
posted:5/14/2011
language:English
pages:11