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

来源:互联网 发布:复杂网络 matlab 编辑:程序博客网 时间:2024/06/04 08:15

一、实验目的:

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

二、实验内容:

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;  }  

四、演示结果:


五、实验结论:

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

原创粉丝点击