关于快速排序的一些优化思考
来源:互联网 发布:js 360全景图 编辑:程序博客网 时间:2024/06/06 04:49
工作快2年了,大学搞算法搞得还算可以,可是毕竟工作之后接触的东西,能用上高级算法的地方少之又少
最近复习了一下数据结构和算法,结合最近学的一些知识,我对快速排序这个算法有了一个新的想法
那就是,将数据按一定区域划分,比如按50W以下,50W-500W,500W-5000W,5000W以上划分4个区域
然后再结合OpenMP的优化指令,启动4个线程去排序这4个区域的数据
那么如果数据划分到区域比较均匀的话,每个区域的数据排序时间期望就是 4 * (n/4) * lg(n/4),时间肯定比n*lgn快不少
关于OpenMP学习的,可以参考IBM写的文章:http://www.ibm.com/developerworks/cn/aix/library/au-aix-openmp-framework/
以下是我的一些测试结果,贴给大家看一下:
数据分布结构:
data01.in:50W以下数据:427500W以下数据:26065000W以下数据:161185000W以上数据:80849data02.in:50W以下数据:4041500W以下数据:256385000W以下数据:1602165000W以上数据:810105data03.in:50W以下数据:20157500W以下数据:1282895000W以下数据:7994295000W以上数据:4052125data04.in:50W以下数据:40933500W以下数据:2559235000W以下数据:15980825000W以上数据:8105062data05.in:50W以下数据:81315500W以下数据:5113075000W以下数据:31933215000W以上数据:16214057data06.in:50W以下数据:121769500W以下数据:7701665000W以下数据:47933585000W以上数据:24314707data07.in:50W以下数据:162871500W以下数据:10236655000W以下数据:63881105000W以上数据:32425354请按任意键继续. . .
使用了OpenMP优化的qsort结果
data01.in:总共耗时:32读入数据时间:18排序所用时间:14data02.in:总共耗时:343读入数据时间:170排序所用时间:173data03.in:总共耗时:1785读入数据时间:814排序所用时间:971data04.in:总共耗时:3610读入数据时间:1614排序所用时间:1996data05.in:总共耗时:7343读入数据时间:3213排序所用时间:4130data06.in:总共耗时:11187读入数据时间:4851排序所用时间:6336data07.in:总共耗时:14994读入数据时间:6464排序所用时间:8530请按任意键继续. . .
没有使用OpenMP优化的qsort结果
data01.in:总共耗时:33读入数据时间:18排序所用时间:15data02.in:总共耗时:340读入数据时间:159排序所用时间:181data03.in:总共耗时:1781读入数据时间:787排序所用时间:994data04.in:总共耗时:3617读入数据时间:1552排序所用时间:2065data05.in:总共耗时:7361读入数据时间:3118排序所用时间:4243data06.in:总共耗时:11206读入数据时间:4670排序所用时间:6536data07.in:总共耗时:15086读入数据时间:6190排序所用时间:8896请按任意键继续. . .
从结果来看,好像并没有什么差异,有可能是编译器自动就会做优化,把运算过程自动交到其他线程去处理吧
也有可能是由于数据分布不均匀,导致效果不明显,不过无论如何,OpenMP版快速排序最多也就退化到原本快速排序应有的效率而已
而且编写难度也没有增加太多,这种思路还是值得探究的
最后,附上我写的一些程序,以供大家研究:
OpenMP版快速排序:
#include <stdio.h>#include <stdlib.h>#include <omp.h>#include <time.h>void qsort(int lt,int rt,int * number);int number[100000];int * range[4];inline int getRange(int num){ if (num > 50000000) return 3; // >5000W if (num > 5000000) return 2; // >500W if (num > 500000) return 1; // >50W return 0;}int main(){ for (int i=0;i<4;++i) { range[i] = new int[50000000]; } int n,num,j,len; char file[100]; FILE * fileIn; for (int Case=1;Case<8;++Case) { sprintf(file,"data%02d.in",Case); //freopen(file,"r",stdin); fileIn = fopen(file,"r"); for (int i=0;i<4;++i) { range[i][0] = 0; } clock_t begin_time = clock(); fscanf(fileIn,"%d",&n); for (int i=1;i<=n;++i) { //读数分类 fscanf(fileIn,"%d",&num); j = getRange(num); len = ++range[j][0]; range[j][len] = num; } clock_t read_finish = clock(); //openmp分布处理 omp_set_num_threads(4); #pragma omp parallel for for (int i=0;i<4;++i) { qsort(1,range[i][0],range[i]); } clock_t sort_finish = clock(); printf("data%02d.in:\n",Case); printf("50W以下数据:%d\n",range[0][0]); printf("500W以下数据:%d\n",range[1][0]); printf("5000W以下数据:%d\n",range[2][0]); printf("5000W以上数据:%d\n",range[3][0]); printf("总共耗时:%d\n",sort_finish - begin_time); printf("读入数据时间:%d\n",read_finish - begin_time); printf("排序所用时间:%d\n",sort_finish - read_finish); fclose(fileIn); } for (int i=0;i<4;++i) { delete [] range[i]; } system("pause"); return 0;}void qsort(int lt,int rt,int * number){ if (rt <= lt) return; int mid = (lt + rt) >> 1; int midVal = number[mid]; int i = lt,j = rt; int tmp; do { while (i < rt && number[i] < midVal) ++i; while (j > lt && number[j] > midVal) --j; if (i <= j) { tmp = number[i]; number[i] = number[j]; number[j] = tmp; ++i; --j; } }while (i <= j); if (i < rt) qsort(i,rt,number); if (lt < j) qsort(lt,j,number);}
正常快速排序:
#include <stdio.h>#include <stdlib.h>#include <time.h>void qsort(int lt,int rt,int * number);int number[50000000];int main(){ int n,num,j,len; char file[100]; FILE * fileIn; for (int Case=1;Case<8;++Case) { sprintf(file,"data%02d.in",Case); //freopen(file,"r",stdin); fileIn = fopen(file,"r"); clock_t begin_time = clock(); fscanf(fileIn,"%d",&n); for (int i=1;i<=n;++i) { fscanf(fileIn,"%d",number+i); } clock_t read_finish = clock(); qsort(1,n,number); clock_t sort_finish = clock(); printf("data%02d.in:\n",Case); printf("总共耗时:%d\n",sort_finish - begin_time); printf("读入数据时间:%d\n",read_finish - begin_time); printf("排序所用时间:%d\n",sort_finish - read_finish); fclose(fileIn); } system("pause"); return 0;}void qsort(int lt,int rt,int * number){ if (rt <= lt) return; int mid = (lt + rt) >> 1; int midVal = number[mid]; int i = lt,j = rt; int tmp; do { while (i < rt && number[i] < midVal) ++i; while (j > lt && number[j] > midVal) --j; if (i <= j) { tmp = number[i]; number[i] = number[j]; number[j] = tmp; ++i; --j; } }while (i <= j); if (i < rt) qsort(i,rt,number); if (lt < j) qsort(lt,j,number);}
数据生成器:
#include <stdio.h>#include <time.h>#include <stdlib.h>int main(){ int n,total; scanf("%d",&n); srand(time(0)); freopen("data.in","w",stdout); printf("%d\n",n); for (int i=0;i<n;++i) { printf("%d ",rand() * rand()); } putchar('\n'); fclose(stdout); return 0;}
0 0
- 关于快速排序的一些优化思考
- 关于堆排序的一些思考
- 排序算法(三)--关于快速排序Partition的思考
- 排序算法(三)--关于快速排序Partition的思考
- 关于快速排序的一些见解(递归和非递归以及优化)
- 快速排序及一些优化
- 白书 - 拓扑排序 及 关于递归、coding的一些思考
- 快速排序的优化
- 快速排序的优化
- 优化的快速排序
- 快速排序的优化
- 快速排序的优化
- 快速排序的优化
- 快速排序的优化
- 快速排序的优化
- 优化的快速排序
- 快速排序的优化
- 快速排序的优化
- Java中的常用类
- 程序开发中解决问题的思路很重要
- Android-02 如何限制 EditText 最大输入字符数
- jQuery(function(){})与(function(){})(jQuery)之间的区别
- 图像卷积和滤波处理-高斯滤波
- 关于快速排序的一些优化思考
- Android Studio系列教程五--Gradle命令详解与导入第三方包
- 【ubuntu操作系统入门】系统安装
- 项目中常用的mysql函数
- WinForm_关于用户控件和自定义控件
- 2812片内ADC采样时间计算
- python在指定行前插入一行
- Andorid检测支付宝客户端是否安装
- c++读写文件设定读和写的位置