Play Scala 71 Step-by-step quicksort

Source: Internet
Author: User

1. Algorithmic thinking

If a sequence is to be sorted, all the numbers are already in the correct position, then the sorting is complete.

Just pick a number and put it in the right place. The left side is unsorted, and the right side is unsorted.

At this point, the problem of sorting on a longer series has been transformed into a sort of two smaller series.

Reference: http://developer.51cto.com/art/201403/430986.htm

Take sequence a = {6, 1, 2, 7, 9, 3, 4, 5, 10, 8} for example

2. In order to put 6 in the correct position (ascending), my first thought is: from the left to the right a number of a number and 6 compared to encounter a smaller than 6 to let it and 6 exchange, then wrote the following Java code (first implemented in Java, and then in Scala implementation)

package algorithm.qs;import java.util.arrays;public class qs {     public static void main (String[] args)  {         integer[] a = {6 , 1,  2, 7,  9,  3,   4,  5, 10 , 8};        int k  = 0;         for  (int i = 0;  i < a.length; i++)  {             if  (A[i] < a[k])  {                 int t = a[i];                 a[i] = a[k];                 a[k] = t;                 k = i;             }        }         system.out.println (Arrays.deeptostring (a));     }}//[1, 2, 3, 7, &NBSP;9,&NBSP;4,&NBSP;5,&NBSP;6,&NBSP;10,&NBSP;8]

But there is a problem: 6 smaller than the 6 to the left, than the 6 is not ranked to the right of 6.


3. Then improve the algorithm, if the encounter than 6 small number B, the number between 6 and B (including 6 does not include B) Move backward 1 bits, put B in the original 6 position

package algorithm.qs;import java.util.arrays;public class qs {     static Integer[] a = { 6, 1, 2, 7, 9, 3, 4,  5,&NBSP;10,&NBSP;8&NBSP;};&NBSP;&NBSP;&NBSP;&NBSP;//&NBSP;[...I...J ...]  => [...j...i ...]     static void swap (INT&NBSP;I,&NBSP;INT&NBSP;J)  {         int t = a[i];        a[i]  = a[j];        a[j] = t;    }     // [...abcd ...]  => [...dabc ...]     static void move (INT&NBSP;I,&NBSP;INT&NBSP;J)  {         while  (I&NBSP;&LT;&NBSP;J)  {             swap (j-1, j);             j--;        }     }        //  will be greater than the first number on the right of the first digit, less than the first number on the first digit left     static void divide ()  {         int k = 0;        for  (int i = 0;  i < a.length; i++)  {             if  (A[i] < a[k])  {                 move (k, i);                 k++;             }        }    }     public static vOid main (String[] args)  {        divide ();         system.out.println (Arrays.deeptostring (a));     }}//[1, &NBSP;2,&NBSP;3,&NBSP;4,&NBSP;5,&NBSP;6,&NBSP;7,&NBSP;9,&NBSP;10,&NBSP;8]

4. How can I sort the entire array without changing too much code? If you want to sort the left and right of 6, you need to divide the part of a. Now the Divide method is implemented to put the first number of the entire array in the correct position, can you give it a part of the array, let it put the first number of this part in the correct position?

The improved divide

package algorithm.qs;import java.util.arrays;public class qs {     final static integer[] a = { 6, 1, 2, 7, 9, 3, &NBSP;4,&NBSP;5,&NBSP;10,&NBSP;8&NBSP;};&NBSP;&NBSP;&NBSP;&NBSP;//&NBSP;[...I...J ...]  => [...j...i ...]     static void swap (INT&NBSP;I,&NBSP;INT&NBSP;J)  {         int t = a[i];        a[i]  = a[j];        a[j] = t;    }     // [...abcd ...]  => [...dabc ...]     static void move (INT&NBSP;I,&NBSP;INT&NBSP;J)  {         while  (I&NBSP;&LT;&NBSP;J)  {             swap (j-1, j);             j--;         }    }        /*     *   The number of positions between S and T is divided into two (including s not including T)      *  is greater than the number of S number on the right, less than the number of s on the left of the number of numbers       */    static int divide (int s, int t)  {         int k = s;         for  (int i = s; i < t; i++)  {             if  (A[i] < a[k])  {                 move (k, i);                 k++;             }        }         return k;    }    static void qsort ( INT&NBSP;S,&NBSP;INT&NBSP;T)  {        int mid =  Divide (s, t);         system.out.println (mid);     }        public static void main (String[]  args)  {        qsort (0, a.length);         system.out.println (Arrays.deeptostring (a));     }}//5//[1, 2, &NBSP;3,&NBSP;4,&NBSP;5,&NBSP;6,&NBSP;7,&NBSP;9,&NBSP;10,&NBSP;8]


5. Last step recursive call Qsort

package algorithm.qs;import java.util.arrays;public class qs {     final static integer[] a = { 6, 1, 2, 7, 9, 3, &NBSP;4,&NBSP;5,&NBSP;10,&NBSP;8&NBSP;};&NBSP;&NBSP;&NBSP;&NBSP;//&NBSP;[...I...J ...]  => [...j...i ...]     static void swap (INT&NBSP;I,&NBSP;INT&NBSP;J)  {         int t = a[i];        a[i]  = a[j];        a[j] = t;    }     // [...abcd ...]  => [...dabc ...]     static void move (INT&NBSP;I,&NBSP;INT&NBSP;J)  {         while  (I&NBSP;&LT;&NBSP;J)  {             swap (j-1, j);             j--;         }    }        /*     *   The number of positions between S and T is divided into two (including s not including T)      *  is greater than the number of S number on the right, less than the number of s on the left of the number of numbers       */    static int divide (int s, int t)  {         int k = s;         for  (int i = s; i < t; i++)  {             if  (A[i] < a[k])  {                 move (k, i);                 k++;             }        }         return k;    }    static void qsort ( INT&NBSP;S,&NBSP;INT&NBSP;T)  {        int mid =  Divide (s, t);        if  (mid > s)  qsort (S,  mid);        if  (t > mid + 1)   Qsort (mid+1, t);    }        public  Static void main (String[] args)  {        qsort (0,  a.length);         system.out.println (Arrays.deepToString (a)); &NBSP;&NBSP;&NBSP;&NBSP;}}//[1,&NBSP;2,&NBSP;3,&NBSP;4,&NBSP;5,&NBSP;6,&NBSP;7,&NBSP;8,&NBSP;9,&NBSP;10]

6. Code Reviews

Although the above code realizes the basic idea of fast sorting, it doesn't show up fast. The time complexity is similar to the insertion sort and bubble sort. The reason is that the move method has too many exchanges. Mathematically speaking, a single exchange reduces the number of reverse order. Fast sorting really embodies the fast place is "jumping" to exchange nonadjacent two numbers, so that the number of reverse order "may" reduce a lot. Below we continue to improve the divide method. This time, two pointers are used to iterate through the array from each end.

package algorithm.qs;import java.util.arrays;public class qs {     final static integer[] a = { 6, 1, 2, 7, 9, 3,  4, 5, 10, 8 };        static void  Swap (INT&NBSP;I,&NBSP;INT&NBSP;J)  {        int t =  a[i];        a[i] = a[j];         a[j] = t;    }         /*     *  divides the number of positions between S and T into two dials (including S excluding T)      *  is greater than the number of numbers on the right of the number of s, less than the number of s on the left side of the number of S      */    static int  Divide (int s, int t)  {        int i =  s, j = t;        while  (I&NBSP;&LT;&NBSP;J)  {             if  (A[j] < a[s])  {                 while  (I&NBSP;&LT;&NBSP;J)  {                      if  (A[i] > a[s])  {                         swap (I,&NBSP;J);                          break;                     }                     i++;                 }            }             if  (I&NBSP;&LT;&NBSP;J)  j--;         }        swap (S,&NBSP;J);         return j;    }     static void qsort (int s, int t)  {         int mid = divide (s, t);         if   (mid > s)  qsort (s, mid);        if  ( t > mid + 1)  qsort (mid+1, t);    }         publiC static void main (String[] args)  {         Qsort (0, a.length-1);         system.out.println ( Arrays.deeptostring (a));     }}

The above code is at least two points not beautiful: 1. All methods have side effects, especially the divide method, which modifies both the external variable and the return value. 2. While, for, if layer nesting makes the code idea very intuitive


7. The Scala version of Quick sort

Package play1object p extends app {  def qsort (List: List[Int]):  list[int] = list match {    case nil => nil     case pivot :: tail =>      val   (smaller, rest)  = tail.partition (_ < pivot)        qsort (smaller)  ::: pivot :: qsort (rest)   }  val a =  list (6, 1, 2, 7, 9, 3, 4, 5, 10, 8)   val b  = qsort (a)   println (b)}  //  was excerpted from the Scala source Def partition (p: A = > boolean):  (REPR,&NBSP;REPR)  = {  val l, r = newbuilder   for  (x <- this)   (if  (P (x))  l else r)  += x    (l.result, r.reSult)} 

This is a complete function of the implementation, although the partition method a little bit of space to change the sense of time. It's not really useful to have a swap here, and the idea is clear.

Play Scala 71 Step-by-step quicksort

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.