随机快速排序(C语言)

分治法基本思想

将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同。递归的解决这些子问题,然后将各个子问题的解合并得到原问题的解。

快速排序

原链接:https://blog.csdn.net/haelang/article/details/44496387

快速排序用到了分治思想,同样的还有归并排序。乍看起来快速排序和归并排序非常相似,都是将问题变小,先排序子串,最后合并。不同的是快速排序在划分子问题的时候经过多一步处理,将划分的两组数据划分为一大一小,这样在最后合并的时候就不必像归并排序那样再进行比较。但也正因为如此,划分的不定性使得快速排序的时间复杂度并不稳定。

快速排序的期望复杂度是O(nlogn),但最坏情况下可能就会变成O(n^2),最坏情况就是每次将一组数据划分为两组的时候,分界线都选在了边界上,使得划分了和没划分一样,最后就变成了普通的选择排序了。

快速排序分为三步分治过程,分解,解决,合并。

分解是将输入数组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]中的所有元素。

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

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

代码

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 10//p,r为边界,先处理左边再处理右边
void QuickSort(int a[],int p,int r)
{if(p<r){int q = Partition(a,p,r);QuickSort(a,p,q-1);QuickSort(a,q+1,r);}
}void Swap(int a[],int left,int right)
{int tmp;tmp = a[left];a[left] = a[right];a[right] = tmp;
}int Partition(int a[],int p,int r)
{int i=p,j=r+1;//本代码的主元选择的是p到r范围内的最左边的即p下标的数int x = a[p];while(1){//将i和j一个从左,一个从右开始相向而行,使得在相遇之前,i部分都是小于x的数,j部分都是大于x的数。左右找到不匹配的数就互换值。while(a[++i]<x && i<r) ;while(a[--j]>x) ;if(i>=j) break;Swap(a,i,j);}//最后把p和j的下标互换一下就可以保证p到r范围内的数,a[j]左边都是小于a[j],右边都是大于a[j],但不代表左边有序或者右边有序,只是单纯的比a[j]小或大在一边而已a[p]=a[j];a[j]=x;return j;
}
int main()
{int a[] = {7,1,5,6,3,8,2,10,9,4};int i;QuickSort(a,0,MAXSIZE-1);for(i=0;i<MAXSIZE;i++){printf("%5d",a[i]);}return 0;
}

随机快速排序

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

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

代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAXSIZE 10
//从范围p到r内找一个下标i,把这个数换到最左边,再进行快速排序Partition。
int RandomizedPartition(int a[],int p,int r)
{srand(time(NULL));int i = rand()%(r-p)+p;Swap(a,i,p);return Partition(a,p,r);
}
//和QuickSort差不多
void RandomizedQuickSort(int a[],int p,int r)
{if(p<r){int q = RandomizedPartition(a,p,r);RandomizedQuickSort(a,p,q-1);RandomizedQuickSort(a,q+1,r);}
}void Swap(int a[],int left,int right)
{int tmp;tmp = a[left];a[left] = a[right];a[right] = tmp;
}int Partition(int a[],int p,int r)
{int i=p,j=r+1;int x = a[p];while(1){while(a[++i]<x && i<r) ;while(a[--j]>x) ;if(i>=j) break;Swap(a,i,j);}a[p]=a[j];a[j]=x;return j;
}
void QuickSort(int a[],int p,int r)
{if(p<r){int q = Partition(a,p,r);QuickSort(a,p,q-1);QuickSort(a,q+1,r);}
}
int main()
{int a[] = {7,1,5,6,3,8,2,10,9,4};int i;//QuickSort(a,0,MAXSIZE-1);RandomizedQuickSort(a,0,MAXSIZE-1);for(i=0;i<MAXSIZE;i++){printf("%5d",a[i]);}return 0;
}

两者性能分析

原文链接:https://blog.csdn.net/haelang/article/details/44496387

随机序列

10w:

算法 第1次耗时 第2次耗时 第3次耗时 平均耗时
普通快排 13ms 15ms 15ms 14.333ms
随机化版本快排 25ms 25ms 27ms 25.667ms

100w:

算法 第1次耗时 第2次耗时 第3次耗时 平均耗时
普通快排 101ms 103ms 96ms 100ms
随机化版本快排 119ms 119ms 105ms 108.333ms

1000w:

算法 第1次耗时 第2次耗时 第3次耗时 平均耗时
普通快排 1397ms 1397ms 1338ms 1371.333ms
随机化版本快排 1241ms 1258ms 1187ms 1228.667ms

随机化快排因为要生成随机数,所以有一些性能损失,所以数据规模较小,数据分布均匀时普通快排还是比随机化快排要快些的,不过随着数据规模的上升,随机化快排的性能优势就展现出来了。

有序序列

假设当输入数组已经是排好序的,这两个算法的性能差距又有多少?

之前的数组生成代码不变,只是在调用两个算法之前,先调用一下快排将数组排序,然后将两个有序的数组作为参数传进去。

10w:

算法 第1次耗时 第2次耗时 第3次耗时 平均耗时
普通快排 溢出 溢出 溢出 溢出
随机化版本快排 15ms 7ms 6ms 9.333ms

1w:

算法 第1次耗时 第2次耗时 第3次耗时 平均耗时
普通快排 98ms 94ms 92ms 94.667ms
随机化版本快排 2ms 1ms 0ms 1ms

1000w:

看下1000w下随机化快排是否有影响

算法 第1次耗时 第2次耗时 第3次耗时 平均耗时
随机化版本快排 696ms 733ms 689ms 706ms

随机快速排序算法(C语言)相关推荐

  1. 随机快速排序算法(java)

    随机快速排序算法最坏时间复杂度O(n^2). 快速排序主要做的任务就是,选取一个基准值x,然后将小于x的值放在区域左边,等于x的值放在中间,大于x的值放在区域的右边.而孙随机快速排序则是从趋于中随机选 ...

  2. 快速排序算法C语言实现

    快速排序算法C语言实现 在任何程序中,数组的排序都是极为重要的内容,我们需要按照业务需要对大量的数据进行排序,因此排序的速度或者说效率就显得极为重要了,因此选择一个效率较高的算法可以大大提升程序的性能 ...

  3. 快速排序实验报告 c语言,快速排序算法c语言实验报告.docx

    快速排序算法c语言实验报告 实验六:冒泡法排序 物理学416班赵增月F12XX日期:XX年10月31日 一·实验目的1.熟练掌握程序编写步骤: 2.学习使用冒泡法和选择法排序: 3.熟练掌握数组的定义 ...

  4. 快速排序算法 c语言实现

    快速排序是一种分治算法,它将一个数组分成两个子数组,将两个子数组分别排序,最终使得整个数组有序. 下面是一个 C 语言实现的快速排序算法: void quick_sort(int *arr, int ...

  5. 快速排序算法-c语言实现,快速排序算法实现(C语言)(转)

    快速排序算法 的基本思想是:将所要进行排序的数分为左右两个部分,其中一部分的所有数据都比另外一 部分的数据小,然后将所分得的两部分数据进行同样的划分,重复执行以上的划分操作,直 到所有要进行排序的数据 ...

  6. 快速排序算法(C语言实现)

    快速排序分三大步骤: 1.分:选择一个分割值并将数据按此分为左右两部分 2.治:分别在两部分用递归方式调用上述的分步骤,继续划分 3.合:对分割的部分排序直至完成 #include <stdio ...

  7. 快速排序算法c语言lomuto,快速排序(N.Lomuto版)

    这个版本的快速排序是由N.Lomuto提出来的. 基本排序步骤如下图所示: /* * 名 称: 快速排序 * 作 者: Brooke gao * 日 期: 2013/6/17 * */ #includ ...

  8. C语言实现随机快速排序random quick sort算法(附完整源码)

    随机快速排序random quick sort算法 随机快速排序random quick sort算法的完整源码(定义,实现,main函数测试) 随机快速排序random quick sort算法的完 ...

  9. 快速排序的随机化算法C语言版

    快速排序的随机化算法C语言版 #include<stdio.h> #include<stdlib.h> void quicksort(int *a, int left, int ...

最新文章

  1. 一个冷僻的知识点try直接返回finally里的设置null其实无效
  2. 在对的时间 遇见对的人 是一种幸福
  3. 如何在生产中检测和诊断慢速代码
  4. js获取当前时间格式YYYY/MM/DD
  5. Python爬虫实战03:用Selenium模拟浏览器爬取淘宝美食
  6. mysql添加语句_Mysql中插入数据语句
  7. linux打开dwg格式文件怎么打开软件,DWG 文件扩展名: 它是什么以及如何打开它?...
  8. matlab 输入Angstrom (埃,埃米,Angstrom 或ANG或Å)
  9. 【C语言】博客之旅从学习C语言开始
  10. cocos creator 3.0见缝插针(口红机)
  11. 【伍】学好财报是选出好公司的关键
  12. mib browser打开mib文件
  13. 交互技术前沿学习分享——利用眼动追踪改良广告界面
  14. mysql workbench安装教程_MySql可视化工具MySQL Workbench使用教程
  15. 3. 清除浮动的几种方式,及其使用
  16. python中集合运算_Python—集合的操作、文件的操作
  17. easyAR学习(一)
  18. 139邮箱发送邮件(python web自动化)
  19. 知网论文免费下载,请速度存好!
  20. WebVR简介和常用资源链接

热门文章

  1. XJOI 1145 选班长
  2. 使用EPIC预测肿瘤微环境中免疫细胞构成
  3. 未来8亿人或被AI无情替代,美国这家创业公司能当好“救火队长”?
  4. 百度提前批校园招聘开始啦!
  5. 互联网创业公司如何防御 DDoS 攻击?
  6. 户口迁移证,报到证和毕业证
  7. 移动互联网已经进入了下半场,你准备好了做下一个主角吗?
  8. C程序设计-谭浩强 第三版-学习笔记 第2章 程序的灵魂 算法
  9. 关于元数据,全网最通俗易懂的文章!
  10. 利用现代OpenGL API大幅度减少由于执行驱动导致CPU的开销