快速排序与随机快速排序

快速排序与随机快速排序

问题描述

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

实验要求

(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);

}

 

 

(二)随机快速排序

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

 

#define max 1000

#define CLOCKS_PRE_SEC ((clock_t)1000)

 

int random_partition(int array[], int p, int r)

{

    int i,m;

    i =rand()%(r-p+1)+p;

    m = array[r];

    array[r] =array[i];

    array[i] = m;

    m =partition(array, p, r);

    return m;

}

 

void random_quicksort(int array[], int p, int r)

{

    if(p < r)

    {

       int q;

       q =random_partition(array, p, r);

       random_quicksort(array,p, q-1);

       random_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("random_quicksortresult:\n");

 

    start =clock();

    random_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 random_quicksort is:%fs!\n",TheTimes);

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值