快速排序学习

     快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据 分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

以上来自百度!


下面是我写的
代码

public function quickSortMe(A:Array,left:int,right:int):void{
                        if(left<right){
                                var p:int=partitionMe(A,left,right)
                                quickSortMe(A,left,p-1);
                                quickSortMe(A,p+1,right);
                        }
                }
                private function partitionMe(A:Array,left:int,right:int):int{
                        //试着把下面两行任意放开一行 测试一下速度的差距!
                        var p:int=left;
//                        var p:int=Math.random()*(right-left)+left;
                        var temp:Number=A[p];
                        A[p]=A[right];
                        A[right]=temp;
                       
                        var store:int=left;
                        for(var i:int=left;i<right;i++){
                                if(A[i]<=temp){
                                        var v:Number=A[store];
                                        A[store]=A[i];
                                        A[i]=v;
                                        store++;
                                }
                        }
                        v=A[right];
                        A[right]=A[store];
                        A[store]=v;
                        return  store;
                }


我这里测试了一下:
n=1000 的情况下
用p=left    需要 100~120毫秒
用p=Math.random()*(right-left)+left;    只需要 4~5 毫秒!

天壤之别啊!


最终优化:
中值的选择,采用 三中值来减少最坏情况的出现。
一下是全部代码:

//↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓插入排序↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓//
                //↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓插入排序↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓//
                //↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓插入排序↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓//
                /**
                 *插入排序
                 * @param p
                 * @return
                 */
                public function insertionSort(p:Array):Array{
                        return _insertionSort(p,0,p.length-1);
                }
                /**
                 *        一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下: 
                 * 1. 从第一个元素开始,该元素可以认为已经被排序
                 * 2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
                 * 3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
                 * 4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
                 * 5. 将新元素插入到该位置中
                 * 6. 重复步骤2
                 * @param p
                 * @param left
                 * @param right
                 * @return
                 */               
                public function _insertionSort(p:Array,left:int,right:int):Array{
                        for(var i:int=left+1;i<=right;i++) {
                                var temp:Number = p[i];
                                for(var j:int=i ; j>0 && temp<p[j-1];j--) {  
                                        p[j]=p[j-1];
                                }
                                p[j]=temp;
                        }
                        return p
                }
                //↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑插入排序↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑//
               
                //↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓快速排序↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓//
                //↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓快速排序↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓//
                //↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓快速排序↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓//
                /**
                 *快速排序
                 * @param A
                 * @param cmp
                 */
                public function quickSortMe(A:Array,left:int,right:int):void{
                        if(left<right){
                                var p:int=partitionMe(A,left,right)
                                if(right-left<7){
                                        _insertionSort(A,left,p);
                                        _insertionSort(A,p,right);
                                }else{
                                        quickSortMe(A,left,p-1);
                                        quickSortMe(A,p+1,right);
                                }
                        }
                }
                /**
                 *
                 * @param A
                 * @param left
                 * @param right
                 * @return
                 *
                 */               
                private function partitionMe(A:Array,left:int,right:int):int{
                        var p:int=medianOf3(A,left,right);
//                        var p:int=Math.random()*(right-left)+left;
                        var temp:Number=A[p];
                        A[p]=A[right];
                        A[right]=temp;
                        var store:int=left;
                        for(var i:int=left;i<right;i++){
                                if(A[i]<=temp){
                                        var v:Number=A[store];
                                        A[store]=A[i];
                                        A[i]=v;
                                        store++;
                                }
                        }
                        v=A[right];
                        A[right]=A[store];
                        A[store]=v;
                        return  store;
                }
                /** 
                 * 三数据选中 
                 * @param left 
                 * @param right 
                 * @return 
                 */ 
                private function medianOf3(A:Array,left:int,right:int):int{  
                        var  center:int = (right-left) / 2+left;  
                        if (A[left] > A[center]) {  
                                swap(A,left, center);  
                        }  
                        if (A[left] > A[right]) {  
                                swap(A,left, right);  
                        }  
                        if (A[center] > A[right]) {  
                                swap(A,center, right);  
                        }
                        return center;
                }


如何优化:
1.切分时的值的选择,如果1~10 需要排序 最理想的中间值是5 因为我们只需要移动赋值一半就OK了对吧?
所以呢先驱们想出了很多办法.....如:
   1.k(中间值)=left或者=right;
     2.k=A[left,right]中的随机的一个元素
   3.在A中 随机取出几个元素 形成|M| 然后再M 中的中值作为 |A|的中值
由于3需要例外的开销!俺放弃了 所以算用随机选择的方法!
2.当问题规模比较小时,我们可以用插入排序!

接下来的时间 俺研究第2个优化方法!


/**
                 *快速排序
                 * @param A
                 * @param cmp
                 */               
                public function quickSortMe(A:Array,left:int,right:int):void{
                        if(left<right){
                                var p:int=partitionMe(A,left,right)
                                if(right-left<20){
                                        _insertionSort(A,left,p);
                                        _insertionSort(A,p,right);
                                }else{
                                        quickSortMe(A,left,p-1);
                                        quickSortMe(A,p+1,right);
                                }
                        }
                }
                private function partitionMe(A:Array,left:int,right:int):int{
                        //试着把下面两行任意放开一行 测试一下速度的差距!
//                        var p:int=left;
                        var p:int=Math.random()*(right-left)+left;
                        var temp:Number=A[p];
                        A[p]=A[right];
                        A[right]=temp;
                        var store:int=left;
                        for(var i:int=left;i<right;i++){
                                if(A[i]<=temp){
                                        var v:Number=A[store];
                                        A[store]=A[i];
                                        A[i]=v;
                                        store++;
                                }
                        }
                        v=A[right];
                        A[right]=A[store];
                        A[store]=v;
                        return  store;
                }
                public function _insertionSort(p:Array,left:int,right:int):Array{
                        for(var i:int=left+1;i<=right;i++) {
                                var temp:Number = p[i];
                                for(var j:int=i ; j>0 && temp<p[j-1];j--) {  
                                        p[j]=p[j-1];
                                }
                                p[j]=temp;  
                        }
                        return p
                }


经过优化之后,数据量小的时候看不出来 比如n=1000 任然一样是 4毫秒!  但是如果达到10W 就会有所改善!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值