快速排列

     ~~~~     快速排列,又称划分交换排序,简称快排,一种排序算法。在平均状况下,排序 n n n个项目要 O ( n l o g   n ) O(nlog~n) O(nlog n)次比较。在最坏状况下则需要 O ( n 2 ) O(n^2) O(n2)次比较,但这次状况并不常见。事实上,快速排序 Θ ( n   l o g   n ) \Theta(n~log~n) Θ(n log n)通常明显比其他算法更快,因为它的内部循环可以在大部分的架构上很有效率的达成。

算法

     ~~~~     快速排序使用分治法策略来吧一个序列分为较小和较大的两个子序列,然后递归地排序两个子序列。
步骤为:

1.挑选基准值:从数组中挑出一个元素,称为“基准”,
2.分割:重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(与基准值相等的数可以放到任何一边)。在这个分割结束之后,对基准值的排序已经完成,
3.递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列。

     ~~~~     递归到最底部的判断条件是数列的大小是零或一,此时该数列显然已经有序。
选取基准值有数种具体方法,次选取方法对排序的时间性能有决定性影响。
在简单的伪代码中,此算法可以被表示为:

 function quicksort(q)
 {
     var list less, pivotList, greater
     if length(q)1 
         return q
     else 
     {
         select a pivot value pivot from q
         for each x in q except the pivot element
         {
             if x < pivot then add x to less
             if x ≥ pivot then add x to greater
         }
         add pivot to pivotList
         return concatenate(quicksort(less), pivotList, quicksort(greater))
     }
 }

原地(in-place)分割版本
上面简单版本的缺点是,他需要 Ω ( n ) \Omega (n) Ω(n)的额外存储空间,也就是跟归并排序一样不好。额外需要的存储器空间配置,在实际上的实现,也会极度影响速度和缓存的性能。有一个比较复杂使用原地分割算法的版本,且在好的基准选择上,平均可以达到 Ω ( l o g n ) \Omega (logn) Ω(logn)空间的使用复杂度。

function partition(a, left, right, pivotIndex)
 {
     pivotValue = a[pivotIndex]
     swap(a[pivotIndex], a[right]) // 把pivot移动到结尾
     storeIndex = left
     for i from left to right-1
     {
         if a[i] <= pivotValue
          {
             swap(a[storeIndex], a[i])
             storeIndex = storeIndex + 1
          }
     }
     swap(a[right], a[storeIndex]) // 把pivot移动到它最后的地方
     return storeIndex
 }

这里原地分割算法,它分割了标示为left和right的序列部分,借由移动小于a[pivotIndex]的所有元素到子序列的开头,留下大于或者等于的元素接在它们后面。在这个过程它也可为基准元素找寻最后摆放的位置,也就是它回传的值。它暂时地把基准元素移到子序列的结尾,而不会被前述方式影响到。由于算法只是用交换,因此最后的数列与原先的数列拥有一样的元素。要注意的是,一个元素在到达它的最后位置前,可能会被交换很多次。
一旦我们有了这个分割算法,要写快速排序本身就很容易了:

procedure quicksort(a, left, right)
     if right > left
         select a pivot value a[pivotIndex]
         pivotNewIndex := partition(a, left, right, pivotIndex)
         quicksort(a, left, pivotNewIndex-1)
         quicksort(a, pivotNewIndex+1, right)

维基百科:快速排序

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值