C语言排序(三)——快速排序与随机化快排

一、实验目的:

快速排序是将问题分解,在众多排序中速度较快,但快速排序存在局限性,在有序序列的排序中速度就会减慢,所以对快速排序进行优化,用随机化快排与快排时间进行比较。

二、实验内容:

1.分解是将输入数组A[l..r]划分成两个子数组的过程。选择一个p,使得a被划分成三部分,分别是a[l..p-1],a[p]和a[p+1..r]。并且使得a[l..p-1]中的元素都小于等于(或大于等于)a[p],同时a[p]小于等于(或大于等于)a[p+1..r]中的所有元素。

2.解决是调用递归程序,解决分解中划分生成的两个子序列。

3.合并是递归到最深层,已经不能再划分成更小的子序列了,便开始合并。因为在分解的时候已经比较过大小,每一个父序列分解而来的两个子序列不仅是有序的,而且合并成一个序列之后还是有序的。因为快排可以在输入数组上进行操作,所以合并这一步不需要编写代码。

4.上面版本的快排在选取主元的时候,每次都选取最右边的元素。当序列为有序时,会发现划分出来的两个子序列一个里面没有元素,而另一个则只比原来少一个元素。为了避免这种情况,引入一个随机化量来破坏这种有序状态。

在随机化的快排里面,选取a[left..right]中的随机一个元素作为主元,然后再进行划分,就可以得到一个平衡的划分。

三、程序代码:

 
#include <stdio.h>  
#include <stdlib.h>  
#include<time.h>  
void display(int array[], int maxlen)  
{  
    int i;  
    for(i = 0; i < maxlen; i++)  
    {  
        printf("%-3d ", array[i]);  
    }  
    printf("\n");  
    return ;  
}   
void swap(int *a, int *b)    
{  
    int temp;  
    temp = *a;  
    *a = *b;  
    *b = temp;  
    return ;  
}  
void quicksort(int array[], int maxlen, int begin, int end)  
{  
    int i, j;  
  
    if(begin < end)  
    {  
        i = begin + 1;  
        j = end;       
            
        while(i < j)  
        {  
            if(array[i] > array[begin])  
            {  
                swap(&array[i], &array[j]);  
                j--;  
            }  
            else  
            {  
                i++;    
            }  
        }  
        if(array[i] >= array[begin]) 
        {  
            i--;  
        }  
        swap(&array[begin], &array[i]);  
          
        quicksort(array, maxlen, begin, i);  
        quicksort(array, maxlen, j, end);  
    }  
}  
int Partition(int *arr, int beg, int end)  
{  
    int j;  
    int sentinel = arr[end];  
    int i = beg-1;  
    for(j=beg; j <= end-1; ++j)  
    {  
        if(arr[j] <= sentinel)  
        {  
            i++;  
            swap(&arr[i], &arr[j]);  
        }  
    }  
    swap(&arr[i+1], &arr[end]);  
    return i+1;  
}    
int RandomPartition(int *arr, int beg, int end)  
{  
    int i = beg + rand() % (end-beg+1);  
    swap(&arr[i], &arr[end]);  
    return Partition(arr, beg, end);  
}  
void RandomQuickSort(int *arr, int beg, int end)  
{  
    if(beg < end)  
    {  
        int pivot = RandomPartition(arr, beg, end);  
        RandomQuickSort(arr, beg, pivot-1);    
        RandomQuickSort(arr, pivot+1, end);  
    }  
}  
// 主函数  
int main()  
{  
    clock_t start,end;
     double    duration;
    int n,i,array[100000];
    printf("请输入快排数组个数:");
    scanf("%d",&n);
    srand(time(NULL));//定义产生随机数组
    for(i=1;i<=n;i++)
    {
        array[i]=rand()%20000+1;
    }
    int maxlen=n;     
    //display(array, maxlen);  
     start=clock(); 
    quicksort(array, maxlen, 0, maxlen-1);  // 快速排序  
      end=clock(); 
       duration = (double)(end- start) / CLOCKS_PER_SEC;
     printf( "快排时间:%f seconds\n", duration ); 
    //display(array, maxlen);  
     srand(time(0));  
    for(i=0; i <n; i++)  
    {  
        array[i] = rand()%20000+1;       
    }  
    start=clock(); 
      RandomQuickSort(array, 0, n-1); 
       end=clock(); 
       duration = (double)(end- start) / CLOCKS_PER_SEC;
       printf( "随机化快排时间:%f seconds\n", duration );
       for(i=1;i<=n;i++)
    {
        array[i]=i;
    }
        start=clock(); 
    quicksort(array, maxlen, 0, n-1);  // 快速排序  
      end=clock(); 
       duration = (double)(end- start) / CLOCKS_PER_SEC;
     printf( "快排有序数组时间:%f seconds\n", duration);
      start=clock(); 
      RandomQuickSort(array, 0, n-1); 
       end=clock(); 
       duration = (double)(end- start) / CLOCKS_PER_SEC;
       printf( "随机化快排有序数组时间:%f seconds\n", duration );
        return 0;  
}  

四、演示结果:


五、实验结论:

    初始为随机的序列,一般情况下且大量数据的前提下,用随机化算法耗时低于确定性算法。同理,初始数组有序时快速排序耗时最长。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值