问题描述:

给定一个未知顺序的n个元素组成的数组,现要利用快速排序算法对这n个元素进行非递减排序。

细节须知:

(1)代码实现了利用递归对数组进行快速排序,其中limit为从已有的随机数文件中输入的所要进行排序的数据的数量(生成随机数并写入文件的过程已在前篇中写出)。

(2)算法主要利用哨兵元素对数据进行分块,递归无限细分之后实现排序。

(3)代码同样利用clock函数对算法的执行时间进行计算以进行算法的效率评估。

(4)为了验证排序结果,代码实现了将排序后的内容输出到同文件夹下的sort_number.txt文件中。

算法原理:

它的完成过程主要是将数组分解为两部分,然后分别对每一部分排序。在划分数组时,是将所有小于某个哨兵元素的项目放到该项目之前,将所有大于该哨兵元素的项目放到该项目之后。哨兵元素可以是任意项目,为方便起见,通常直接选择第一个项目。因而可以总结为三步:(1)分解;(2)递归求解;(3)合并。其中,算法的核心部分为对数组进行划分,将小于x的元素放在原数组的左半部分,将大于x的元素放在原数组的右半部分。

 #include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using namespace std;
#define limit 100000 void quicksort(int a[], int low ,int high)
{
if(low<high){ //递归的终止条件
int i = low, j = high; //使用i,j在对应区间内对数组进行排序;
int x = a[low]; //将数组的第一个元素作为哨兵,通过这种方式取出哨兵元素 while(i < j){
while(i < j && a[j] >= x)
j--; //从右向左寻找第一个比哨兵元素小的元素
if(i < j){
a[i] = a[j];
i++; //把找到的第一个小于哨兵元素的元素值赋值给第一个元素,并把下界(i)向后移一位
} while(i < j && a[i] <= x)
i++; //从左向右寻找第一个比哨兵元素大的元素
if(i < j){
a[j] = a[i];
j--;
} //把找到的第一个大于哨兵元素的元素值赋值给下标为j的元素,并把上界(j)向前移一位
}
a[i] = x; //把哨兵赋值到下标为i的位置,i前的元素均比哨兵元素小,i后的元素均比哨兵元素大 quicksort(a, low ,i-); //递归进行哨兵前后两部分元素排序
quicksort(a, i+ ,high);
}
}
int main(void)
{
ifstream fin;
ofstream fout;
int x;
int i;
int a[limit]; fin.open("random_number.txt");
if(!fin){
cerr<<"Can not open file 'random_number.txt' "<<endl;
return -;
}
time_t first, last; for(i=; i<limit; i++){
fin>>a[i];
}
fin.close(); first = clock(); quicksort(a,,limit-); last = clock(); fout.open("sort_number.txt"); if(!fout){
cerr<<"Can not open file 'sort_number.txt' "<<endl;
return -;
}
for(i=; i<limit; i++){
fout<<a[i]<<endl;
} fout.close(); cout<<"Sort completed (already output to file 'sort_number.txt')!"<<endl;
cout<<"Time cost: "<<last-first<<endl; return ;
}

程序设计思路:

(1)分解:以a[p]为基准元素将a[p:r]划分成3段a[p:q-1],a[q]和a[q+1:r],使得a[p:q-1]中任何元素小于等于a[q],a[q+1:r]中任何元素大于等于a[q]。下标q在划分过程中确定。

(2)递归求解:通过递归调用快速排序算法,分别对a[p:q-1]和a[q+1:r]进行排序。

(3)合并:由于对a[p:q-1]和a[q+1:r]的排序是就地进行的,所以在a[p:q-1]和a[q+1:r]都已排好序后不需要执行任何计算,a[p:r]就已排好序。

结果数据格式为time_t格式相减得到的长整型以及输出到文件的整形数据。

时间复杂性分析:

对于输入序列a[p:r],算法的计算时间显然为O(r-p-1).

快速排序的运行时间与划分是否对称有关,其最坏情况发生在划分过程中产生的两个区域分别包含n-1个元素和1个元素的时候。由于算法的计算时间为O(n),所以如果算法的每一步都出现这种不对称划分,则其计算时间复杂性T(n)满足

T(n)= O(1),n≤1

T(n)= T(n-1)+O(n),n>1

解此递归方程可得T(n)=O(n²)。

在最好情况下,每次划分所取的基准都恰好为中值,即每次划分都产生两个大小为n/2的区域,此时,算法的计算时间T(n)满足

T(n)= O(1),n≤1

T(n)= 2T(n/2)+O(n),n>1

其解为T(n)=O(nlogn)。

可以证明,快速排序算法在平均情况下的时间复杂性也是O(nlogn)。

最新文章

  1. Red5 1.0.0RC1 集成到tomcat6.0.35中运行&amp;部署新的red5项目到tomcat中
  2. WebService的开发、部署、调用
  3. jQuery源码分析系列(40): 动画设计
  4. Eclipse启动分析
  5. Java线程(二):线程同步synchronized和volatile
  6. unity3d摄像机入门01
  7. Mysql 不同版本 说明
  8. IOS 单例 创建方式
  9. Linux改IP后务必重启网络服务
  10. 查找类class所在的jar包
  11. 游戏开发设计模式之状态模式 &amp; 有限状态机 &amp; c#委托事件(unity3d 示例实现)
  12. android实现界面左右滑动(GridView动态设置item,支持每个item按某个属性排序来显示在不同的界面)
  13. Linux基本命令之用户系统相关命令
  14. SpringBoot入门教程(十七)@Service、@Controller、@Repository、@Component
  15. (hdu) 4857 逃生 (拓扑排序+优先队列)
  16. easyui时的时间格式yyyy-MM-dd与yyyy-MM-ddd HH:mm:ss
  17. 企业面试题-find结合sed查找替换
  18. 清除EasyUi combotree下拉树的值
  19. Cocos Creator 的实现拖尾效果
  20. oracle tuning 工具

热门文章

  1. planAhead的启动时间较长
  2. HTML引入外部JS文件
  3. NSGA-II算法学习
  4. linux操作系统与jvm
  5. hdu2094产生冠军[STL set]
  6. 【Beta】设计与计划
  7. Android如何屏蔽home键和recent键
  8. 多线程高效合作之master-warker模式
  9. SSL证书原理讲解
  10. FastStone Capture 9.3 强烈推荐,常用功能介绍