关于Quick Sort

看了书和视频,但是觉得还是维基百科上的容易理解:

1. 简单的quick sort伪代码如下:

 function quicksort('array')
      if length('array')1
          return 'array'  // an array of zero or one elements is already sorted
      select and remove a pivot element 'pivot' from 'array'  // see 'Choice of pivot' below
      create empty lists 'less' and 'greater'
      for each 'x' in 'array'
          if 'x''pivot' then append 'x' to 'less'
          else append 'x' to 'greater'
      return concatenate(quicksort('less'), list('pivot'), quicksort('greater')) // two recursive calls
这个和Merge sort的伪代码有异曲同工之妙:

function merge_sort(list m)
    // if list size is 0 (empty) or 1, consider it sorted and return it
    // (using less than or equal prevents infinite recursion for a zero length m)
    if length(m) <= 1
        return m
    // else list size is > 1, so split the list into two sublists
    // 1. DIVIDE Part...
    var list left, right
    var integer middle = length(m) / 2
    for each x in m before middle
         add x to left
    for each x in m after or equal middle
         add x to right
    // recursively call merge_sort() to further split each sublist
    // until sublist size is 1
    left = merge_sort(left)
    right = merge_sort(right)
    // merge the sublists returned from prior calls to merge_sort()
    // and return the resulting merged sublist
    // 2. CONQUER Part...
    return merge(left, right)
在这里:quick sort把难的部分优先解决了,最好的情况用的时间是 O( n  log  n), 但是最坏的情况会是( O( n 2 (extremely rare).

2. 但是simple的quick sort问题就是对于memory的占用太多了,所以有了inplace quick sort

首先理解partition的伪代码:

// left is the index of the leftmost element of the subarray
   // right is the index of the rightmost element of the subarray (inclusive)
   //   number of elements in subarray = right-left+1
   function partition(array, left, right, pivotIndex)
      pivotValue := array[pivotIndex]
      swap array[pivotIndex] and array[right]  // Move pivot to end
      storeIndex := left
      for i from left to right - 1  // left ≤ i < right
          if array[i] < pivotValue
              swap array[i] and array[storeIndex]
              storeIndex := storeIndex + 1
      swap array[storeIndex] and array[right]  // Move pivot to its final place
      return storeIndex
通过partition可以将array按照<p pivot >p 的顺序排好
 
之后就有了下面的quick sort伪代码:
function quicksort(array, left, right)
 
      // If the list has 2 or more items
      if left < right
 
          // See "Choice of pivot" section below for possible choices
          choose any pivotIndex such that left ≤ pivotIndex ≤ right
 
          // Get lists of bigger and smaller items and final position of pivot
          pivotNewIndex := partition(array, left, right, pivotIndex)
 
          // Recursively sort elements smaller than the pivot
          quicksort(array, left, pivotNewIndex - 1)
 
          // Recursively sort elements at least as big as the pivot
          quicksort(array, pivotNewIndex + 1, right)

因为上一次的partition代码返回的是P的index,就是分界线的index,在subroutine里面的界限就是left到p-1,和p+1到right。之后recursive调用直到array书目小于等于1.从而返回array本身。


3. 关于P的选择


quick sort 方法不稳定,在p不同的时候很可能有截然不同的结果,因此P的选择就成为一个很重要的问题。R Sedgewick推荐的是,或者我们用random方法来选择p,或者分割时候选择middle index(这个也会有问题)。总的来说P的选择还是很复杂的。random的方法就能够实现时间为O(nlogn)。 




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值