快速排序与随机快速排序

快速排序与随机快速排序

问题描述

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

实验要求

(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("\nquicksortresult:\n");
    start =clock();
    quicksort(array,0 ,max-1);
    finish =clock();

    for(i = 0; i< max; i++)
       printf("%d\n",array[i]);

    TheTimes =(double)((finish - start)/CLOCKS_PRE_SEC);
    printf("Thetime of quicksort is:%fs!\n",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:\n");
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\n",array[i]);
144 
145     TheTimes = (double)((finish- start)/CLOCKS_PRE_SEC);
146 
147     printf("Thetime of random_quicksort is:%fs!\n",TheTimes);
148 
149 }

 

 

猜你喜欢

转载自www.cnblogs.com/jayinnn/p/9559267.html