• 随机方法避免快排最坏情况,快排中引入插入排序提速分析


    1快速排序算法基本思想:

    QuickSort(A,p,r)

             if p<r

                       then q<- PARTITION(A,p,r) 1//选择位置q,将数组分为两部分

                       QuickSort(A,p,q-1)     

                       QuickSort(A,q+1,r)

    PARTITION(A,p,r)

             x<- A[r]

             i<- p-1     //定义i为活动指针,向右移动并使A[p…i]<=x

             for j<- p to r-1  //定义j为遍历数组A

                       do if A[j]<= x

                                then i< i+1 //右移并交换,使满足<=x的元素增加一个

                                         exchange A[i]<->A[j]

             exchange A[i+1]<->A[r] 

    //将A[r]放入i+1位置,使p…i项均小于i+1项,后A[i+2…r]项均大于A[i+1]

             return i+1

    2改进优化方法:

    一、通过采用随机方法,避免最坏情况发生:

    在原方法中,选择比较元素为数组最后一个元素。通过随机函数,生成位于p~r之间的随机数为比较项位置(A[random(p,r)]),与原先比较元素(A[r])位置交换,再调用PARTITION方法,伪代码如下:

    //该方法能对数组中已经存在部分有序队列的情况进行优化,避免最坏情况发生

    Random_PARTITION(A,p,r)

             i<- Rand(p,r)

             exchange A[i]<->A[r]

    return PARTITION(A,p,r)

             将Random_PARTITION方法在1处调用即可。

    二、当问题规模小于某一k值时,采用插入排序,提高算法效率

    修改当r-p<k值时,调用InsertSort方法

    修改后方法伪代码为:

    QuickSort(A,p,r)

             if r-p<k

                       InsertSort(A,p,r)

             else if p<r

                       then q<- Random_PARTITION (A,p,r)

                       QuickSort(A,p,q-1)     

                       QuickSort(A,q+1,r)

            

    k值的讨论取值:

    算法复杂度为O(nk+nlog(n/k)),对于每一项的系数有插入排序复杂度为0.5*k*(k-1)*(n/k)=1/2*n*k,可以取nk项系数为c1=1/2。对于采用原快排序的部分,有期望为nlog(n/k),通过递归树证明略,取c2=1,则有下式:

    令F(k)= c1*nk+c2*nlog(n/k)=0.5*nk+nlog(n/k)

    对F(k)求导,一阶导数=0,二阶导数>0,则有:

    k=2/ln2

    对k取值约等于3时有最小值,即问题规模<=3时采用插入排序效率更高。

    对K值的讨论:

    k=3时 0.20s

    k=6时0.18s

    k=7时0.18s

    k=50时0.19s

    k=100时0.20s

    分析,因为实验环境是core i5 处理器能力较强,对于1000000(1百万)数据时间耗时较短差别较小。在k取7~30左右可有较好范围的实验结果。

    实验结果:

    实验环境:Ubuntu_x64语言:C++ 数据规模:

    实验数据1000000 处理器i5 4核

    采用插入排序优化后结果:耗时0.194s  k取值为4

    直接使用快排结果:耗时0.203S

    采用随机方法于原算法比较:

    对已经排好序的数组进行排序,对最坏情况进行分析:

    问题规模:10000 不采用random 0.138S

    采用random方法0.002s

    实验结果明显,通过采用随机元素位置,可以避免坏情况带来的特殊值,使算法更接近于时间期望。

    原文链接:http://www.cnblogs.com/sunshinewill/archive/2013/03/05/2943642.html

    View Code
    #include <iostream>
    #include <time.h>
    #include <stdlib.h>
    using namespace std;
    void Insertsort(int list[],int a,int b){
        int next,j;
        if(a>b)return;
        for(int x=a;x<=b;x++){
        next=list[x];
        for(j=x-1;j>=a&&next<list[j];j--)
            list[j+1]=list[j];
        list[j+1]=next;
        }
    
    }
    
    void quicksort(int list[],int left,int right)
    {
     int pivot,i,j;
     int temp,pos;
     //k取值为10
     if(right-left<10){Insertsort(list,left,right);}else
     if(left<right)
     {//注明:在实现过程中,采用i,j从两边向中间遍历的方法,可进一步提高算法的速度
      i=left;
      j=right+1;
      pos=rand()%(right-left)+left;//采用随机方法
     pivot=list[pos];
      temp=list[left];
      list[left]=list[pos];
      list[pos]=temp;
    //pos =left;
      do
      {
       do i++;
       while(list[i]<pivot);
     
       
       do j--;
       while(list[j]>pivot);
       if(i<j)
       {temp=list[i];
       list[i]=list[j];
       list[j]=temp;}
      }while(i<j);
    
      temp=list[left];
      list[left]=list[j];
      list[j]=temp;
      quicksort(list,left,j-1);
      quicksort(list,j+1,right);
     }
     else return;
    }
    
    int main()
    {
     int i;
     int n=1000000;
     int list[1000000];
    
     srand((unsigned)time(NULL));
     for(i=0;i<n;i++)
     list[i]=rand();
    
     quicksort(list,0,n-1);
    // for(i=0;i<n;i+=20)
    // cout<<" "<<list[i];
    
     return 0;  
    }
  • 相关阅读:
    Pycharm 设置python文件自动生成头部信息模板
    Python3.0 调用HTMLTestRunner生成的报告中不能显示用例中print函数的输出
    Python3.0 操作MySQL数据库执行SQL语句
    js时间戳转为日期格式
    Vue脚手架(vue-cli)安装总结
    Vue的生命周期
    常用的ES6语法
    学习python登录demo
    CSS的垂直居中和水平居中总结
    CSS清除浮动方法总结
  • 原文地址:https://www.cnblogs.com/sunshinewill/p/2943642.html
Copyright © 2020-2023  润新知