Sort of fast row

  • Sorting a string of data is incremented or decremented in accordance with the size of its operation are arranged one or some of the keywords I, usually is sorted in ascending order, sorting is ordered in situ
  • Quick sort under the following description, referred to as fast row

Fast row

  • principle:
    • Selecting a number from the range to be sorted, as a reference value (Pivot)
    • Partition: traverse the entire interval to be sorted, smaller than the reference value (which may contain equal) into the left side of the reference value, (may contain equal) than the reference value, a large reference value into the right
    • Partition using thought, between the left and right of the two cells treated in the same manner, until a length equal to the inter-cell 1, it has been ordered on behalf of, or equal to the length between cell 0, representing no data.
  • Fast row is a sort of instability

Method to realize

  1. Fast row logic is very simple,

    • Recursive divide and conquer
    • code show as below:

      public static void quickSort(int[] array) {
              //待排序区间为[0, array.length - 1]
              quickSortIternal(array, 0, array.length - 1);
      }
      
      private static void quickSortIternal(int[] array, int left, int right) {
              if(left >= right)
                      return;
      
              //这里的就选择最左边的元素作为基准值来操作
              //index表示基准值停留的下标
              int index = partition(array, left, right);
      
              quickSortIternal(array, left, index - 1);
              quickSortIternal(array, index + 1, right);
      }
    • Non-recursive divide and conquer
    • By using the stack implementation, the left subscript of the array into the stack
    • Analyzing the relationship between each of the left and right removed, if left> = right indicates the inter-cell sorted
    • Each section into two left and right subscripts in cycles, when the stack is empty, indicating the end of the sort
    • code show as below:

      public static void quickSort2(int[] array) {
                  Stack<Integer> stack = new Stack<>();
                  stack.push(array.length - 1);
                  stack.push(0);
      
                  while(!stack.isEmpty()) {
                          int left = stack.pop();
                          int right = stack.pop();
      
                          if(left >= right) {
                                  continue;
                          }
      
                          int index = partition(array, left, right);
      
                          stack.push(right);
                          stack.push(index + 1);
      
                          stack.push(index - 1);
                          stack.push(left);
                  }
          }
  2. It focused on achieving the partition

    • A realization: Hoare law
    • Use of double reference, a pointer to the leftmost section, a pointer to the rightmost section, two reference traversal closer to the middle of the
    • If the left reference value is equal to the reference value is smaller than the point moves
    • If the right point to a reference value is not less than the reference value is moved
    • When the left data is greater than the reference value of the reference face of the reference data and the right face than the reference value, the exchange of data both at the reference
    • When two references meet the end of this description partition, returned to the reference value of the subscript
    • code show as below:

      public int partition(int[] array, int left, int right) {
                  int pivot = array[left];
                  int l = left;
                  int r = right;
      
                  while(l < r) {
                          while(l < r && array[r] >= pivot) {
                                  r--;
                          }
                          while(l < r && array[l] <= pivot) {
                                  l++;
                          }
                          swap(array, l, r);
                  }
                  swap(array, left, l);
                  return l;
          }
      
          private static void swap(int[] array, int i, int j) {
                  int tmp = array[i];
                  array[i] = array[j];
                  array[j] = tmp;
          }
    • Implementation II: filled pit method
    • Also need double quote, specify a variable to hold the reference value, the reference value of the position the illusion of a "pit"
    • Right encountered reference value greater than or equal to the reference value moves to the left, until the first value is less than the reference value, the fill value to "pit", the position here is a new "pit"
    • He began to move left reference only encountered a value greater than the reference value, to fill the "hole" in the
    • Description encounter until the left and right quote reference only last a pit, to fill the reference value "pit", the return value of the reference index, the end of this partition
    • code show as below:

      public int partition(int[] array, int left, int right) {
          int pivot = array[left];
          int l = left;
          int r = right;
      
          while(l < r) {
                  while(l < r && array[r] >= pivot) {
                          r--;
                  }
                  array[l] = array[r];
                  while(l < r && array[l] <= pivot) {
                          l++;
                  }
                  array[r] = array[l];
          }
          array[l] = pivot;
          return l;
      }
    • Implementation III: before and after traversing method
    • After double references also slow and fast, while the initial value of a reference point element left + 1
    • Reference fast backward traversal, if the traverse to a value larger than the reference value is moved rearwardly
    • The face value than the reference value, and fast exchange of references cited slow points value, a slow backward movement
    • Always guaranteed before slow is smaller than the threshold value, between the slow and fast are greater than the reference value equal to the value, when the section is moved to the rightmost fast right, ending traversal
    • show case - at a value smaller than the reference value is the last end of the traversal the value of the most
    • 1 at the two position values, SLOW - - SLOW exchange left and subscript 1 indicates a subscript that is a reference value, the process returns slow - 1
    • code show as below:

      private int partition(int[] array, int left, int right) {
                  int pivot = array[left];
                  int slow = left + 1;
                  int fast = left + 1;
      
                  while(fast <= right) {
                          if(array[fast] < pivot) {
                                  swap(array, slow, fast);
                                  slow++;
                          }
                          fast++;
                  }
                  swap(array, left, slow - 1);
                  return slow - 1;
          }
  3. Select the reference value
    • Whichever one sides (left or right)
    • random selection
    • Taken in a few number (for example three in number taken: array [left], array [mid], array [right] is the size of the intermediate value as a reference)

Performance Analysis

  • time complexity:
    • Best case: O (N * logN)
    • Average case: O (N * logN)
    • The worst case: O (N ^ 2)
  • Space complexity: O (1)
    • Best case: O (logN)
    • Average case: O (logN)
    • The worst case: O (N)
  • Stability: Unstable

Guess you like

Origin blog.51cto.com/14233687/2472125