zoukankan      html  css  js  c++  java
  • 快速排序与随机快速排序

    快速排序与随机快速排序

    问题描述

        实现对数组的普通快速排序与随机快速排序。

    实验要求

    (1)实现上述两个算法 

    (2)统计算法的运行时间

    (3)分析性能差异,作出总结

    算法原理

    (一)快速排序

        通过使用分治思想对快速排序算法进行描述。下面对一个典型的子数组A[p…r]进行快速排序的三步分治过程:

        分解:数组A[p…r]被划分为两个(可能为空)子数组A[p…q-1]和A[q+1…r],使得A[p…q-1]中的每一个元素都小于等于A[q],而A[q]也小于等于A[q+1…r]中的每个元素。其中,计算下标q也是划分过程的一部分。

        解决:通过递归调用快速排序,对于数组A[p…q-1]和A[q+1…r]进行排序。

        合并:因为子数组都是原址排序的,所以不需要合并操作:数组A[p…r]已近有序。

     

    关键代码实现:

    (一)实现快速排序:

    QUICKSORT(A,p,r)

    1 if p < r

    2     q = PARTITION(A,p,r)

    3     QUICKSORT(A,p,q-1)

    4     QUICKSORT(A,q+1,r)

     

    (二)数组的划分:

    PARTITION(A,p,r)

    1 x = A[r]

    2 i = p-1

    3 for j = p to r-1

    4     if A[j] <= x

    5         i = i + 1

    6         exchange A[i]with A[j]

    7 exchange A[i+1] with A[r]

    8 return i+1

     

    (二)随机快速排序

        随机快速排序与始终采用A[r]作为主元的方法不同,通过采用一种随机抽样的随机化技术,使得从子数组A[p…r]中随机选择一个元素作为主元。为达到这一目的,首先将A[r]从A[p…r]中随机选出的一个元素交换。通过对序列p,…,r的随机抽样,我们可以保证主元元素x=A[r]是等概论地从子数组的r-p+1个元素中选取的,由于主元素是随机选取的,使得对输入数组的划分也是比较均衡的,从而获得较好的期望性能。 

    关键代码实现:

    (一)随机数组的调用:

    RANDOMIZED-PARTITION(A,p,r)

    1 i = RANDOM(p,r)

    2 exchange A[r] with A[i]

    3 return PARTITION(A,p,r)

     

    (二)函数PARTITION(A,p,r)仍调用快速排序的PARTITOON(A,p,r)函数

    说明:快速排序过程中,调用QUICKSORT()和PARTITION()函数进行数组内部的快速排序;对于随机快速排序,则调用RANDOMIZED-PARTITION()来选取随机的关键字(key),再通过QUICKSORT()和PARTITION()函数进行排序。

     

    实验截图

    10个元素快速排序的实验结果:

    10000个元素快速排序的实验结果:

    10个元素随机快速排序的实验结果:

    10000个元素随机快速排序的实验结果:

    结果分析

    (一)从原理上分析,快速排序的最坏运行时间是Θ(n2),即在每次进行PARTITION(A,p,r)函数对数组A进行划分时,都出现主元素在划分区域的某一侧,使得划分区域的元素都小于或大于主元素;期望运行时间是Θ(nlgn),在随机快速排序中,运行RANDOMIZED_PARTITION(A,p,r)后每次选取主元素都能使得主元素在划分区域的中间。

    (二)从实际的运行过程中,实验随机生成10、10000个数据进行排序,并比较了运行排序代码的时间。实验出现中,运行时间未出现较大区分度的原因:一方面是因为在普通快速排序过程中,数组是随机生成的,这样使得在每次选取主元时,和随机快速排序相似,从而二者区分度不高;另一方面,电脑主频较高、选取的实验数据不够大也会使二者区分度不高。

      

    附录(代码)

    (一)普通快速排序

    #include <stdio.h>
    
    #include <stdlib.h>
    
    #include <time.h>
    
    
    #define max 10000
    
    #define CLOCKS_PRE_SEC ((clock_t)1000)
    
    
    void quicksort(int array[], int p, int r)
    
    {
        if(p < r)
        {
           int q;
           q =partition(array, p, r);
           quicksort(array,p, q-1);
           quicksort(array,q+1, r);
        }
    }
    
    int partition(int array[], int p, int r)
    {
        int x,m,i,j;
        x = array[r];
        i = p-1;
        for(j = p; j<= r-1; j++ )
        {
           if(array[j]<= x)
           {
               i = i+ 1;
               m =array[i];
               array[i]= array[j];
               array[j]= m;
           }
        }
        m =array[i+1];
        array[i+1] =array[r];
        array[r] = m;
        return (i+1);
    }
    
    int main()
    {
        intarray[max];
        int i = 0;
        clock_tstart,finish;
        doubleTheTimes;
        for(i = 0; i< max; i++)
        {
           array[i] =rand()%10000;
           printf("%d  ",array[i]);
        }
        printf("
    quicksortresult:
    ");
        start =clock();
        quicksort(array,0 ,max-1);
        finish =clock();
    
        for(i = 0; i< max; i++)
           printf("%d
    ",array[i]);
    
        TheTimes =(double)((finish - start)/CLOCKS_PRE_SEC);
        printf("Thetime of quicksort is:%fs!
    ",TheTimes);
    
    }

     

    (二)随机快速排序

      1 #include <stdio.h>
      2 
      3 #include <stdlib.h>
      4 
      5 #include <time.h>
      6 
      7  
      8 
      9 #define max 1000
     10 
     11 #define CLOCKS_PRE_SEC ((clock_t)1000)
     12 
     13  
     14 
     15 int random_partition(int array[], int p, int r)
     16 
     17 {
     18 
     19     int i,m;
     20 
     21     i =rand()%(r-p+1)+p;
     22 
     23     m = array[r];
     24 
     25     array[r] =array[i];
     26 
     27     array[i] = m;
     28 
     29     m =partition(array, p, r);
     30 
     31     return m;
     32 
     33 }
     34 
     35  
     36 
     37 void random_quicksort(int array[], int p, int r)
     38 
     39 {
     40 
     41     if(p < r)
     42 
     43     {
     44 
     45        int q;
     46 
     47        q =random_partition(array, p, r);
     48 
     49        random_quicksort(array,p, q-1);
     50 
     51        random_quicksort(array,q+1, r);
     52 
     53     }
     54 
     55 }
     56 
     57  
     58 
     59 int partition(int array[], int p, int r)
     60 
     61 {
     62 
     63     int x,m,i,j;
     64 
     65     x = array[r];
     66 
     67     i = p-1;
     68 
     69     for(j = p; j<= r-1; j++ )
     70 
     71     {
     72 
     73        if(array[j]<= x)
     74 
     75        {
     76 
     77            i = i+ 1;
     78 
     79            m =array[i];
     80 
     81            array[i]= array[j];
     82 
     83            array[j]= m;
     84 
     85        }
     86 
     87     }
     88 
     89     m =array[i+1];
     90 
     91     array[i+1] =array[r];
     92 
     93     array[r] = m;
     94 
     95  
     96 
     97     return (i+1);
     98 
     99 }
    100 
    101  
    102 
    103 int main()
    104 
    105 {
    106 
    107     intarray[max];
    108 
    109     int i = 0;
    110 
    111     clock_tstart,finish;
    112 
    113     doubleTheTimes;
    114 
    115  
    116 
    117  
    118 
    119     for(i = 0; i< max; i++)
    120 
    121     {
    122 
    123        array[i] =rand()%10000;
    124 
    125        printf("%d  ",array[i]);
    126 
    127     }
    128 
    129     printf("random_quicksortresult:
    ");
    130 
    131  
    132 
    133     start =clock();
    134 
    135     random_quicksort(array,0 ,max-1);
    136 
    137     finish =clock();
    138 
    139  
    140 
    141     for(i = 0; i< max; i++)
    142 
    143        printf("%d
    ",array[i]);
    144 
    145     TheTimes = (double)((finish- start)/CLOCKS_PRE_SEC);
    146 
    147     printf("Thetime of random_quicksort is:%fs!
    ",TheTimes);
    148 
    149 }

     

     

    说明:所有内容仅做学习记录
  • 相关阅读:
    Git 常用命令汇总
    Vue 双向绑定原理
    移动端开发调试总结
    GPU硬件加速
    对象方法、类方法、原型方法 && 私有属性、公有属性、公有静态属性
    页面跳转
    引用对象深度赋值
    grunt、Browsersync服务及weinre远程调试
    Promise
    数据库Job定时任务
  • 原文地址:https://www.cnblogs.com/jayinnn/p/9559267.html
Copyright © 2011-2022 走看看