分治法的简单应用

1.将序列A(0:n-1)中元素按照升序排序。

 方法:归并排序和快速排序

  要求:

  (1)对于快速排序,主元采用三者A(low),A(high),A((low+high)/2)中其值居中者。

  (2)随机产生20组数据(比如n=5000i,1≤i≤ 20),数据均属于范围(0,105)内的整数。对于同

数据,运行快速分类和归并分类算法,并计录各自的运行时间(以毫秒为单位),比较两种分类算法在

平均情况下哪一个更快。

2.选择问题:找出序列A(0:n-1)中的第k小元素。

           特别地,当k=én/2ù时,即找中值元素。

随机数的产生

需调用的函数

srand(unsigned int )

功能:设置产生随机数的种子,通常以系统时间做种子函数原型: void srand( unsigned int seed );

需要的头文件: <stdlib.h>

返回值:无返回值

rand()

功能:产生一个伪随机数.

函数原型: int rand( void );

需要的头文件: <stdlib.h>'

返回值:返回一个伪随机数,通常范围在0 - 0xfffp内。

获取系统时间

为了记录某函数的实际运行时间,我们可以调用如下函数,该函数可精确到毫秒

#include< <windows.h>

DWORD time,begin=GetTickCountO;

函数调用语句

time=GetTickCount()-begin;cout< << <time< < <"ms";

#include<iostream>
#include<ctime>
#include<cmath>
using namespace std;
//merge function
//使用一个数组作为容器存放合并后的数值然后返回给原数组
void merge(double array[],int low,int mid,int high){//合并函数
double *temp = new double[high-low+1];
int i=0,j=0,num=0;
for(;i<=mid-low&&j<=high-mid-1;num++){
if(array[low+i]<array[mid+1+j]){
temp[num] = array[low+i];
i++;
}
else{
temp[num] = array[mid+1+j];
j++;
}
}
if(j>high-mid-1){
for(;low+i<=mid;i++,num++)
temp[num] = array[low+i];
}else{
for(;j+mid+1<=high;j++,num++)
temp[num] = array[j+mid+1];
}
for(int c=low;c<=high;c++){
array[c] = temp[c-low];
}
}
 
//mergesort
void mergesort(double array[],int low,int high){
if(high>low){
int mid =(high+low)/2;
mergesort(array,low,mid);
mergesort(array,mid+1,high);
merge(array,low,mid,high);
}
}
 
//find_mid function
//找出low、high、mid中中间大小的数与low位置的数交换作为分离值
void find_mid(double array[],int low,int high){
int mid=(low+high)/2,temp;
if((array[low]<=array[high]&&array[low]>=array[mid])||(array[low]>=array[high]&&array[low]<=array[mid])){
temp = low;
}else if((array[mid]<=array[low]&&array[mid]>=array[high])||(array[mid]>=array[low]&&array[mid]<=array[high])){
temp = mid;
}else{
temp = high;
}
swap(array[low],array[temp]);
}
 
//split function
//把数组分成大小两部分
void split(double array[],int &w,int low,int high){
        
        find_mid(array,low,high);
int i = low;
        double x = array[low];
        for(int j= low+1;j<=high;j++){
            if (array[j]<=x) {                 //1号标记处
                i = i+1;
                if (i != j) {
                    swap(array[i],array[j]);
                }
            }
        }
        swap(array[i],array[low]);
        w = i;
  }
 
//quicksort function
void quicksort(double array[],int low,int high){
     int w;
    if (low < high) {
        split(array,w,low,high);
   quicksort(array,low,w-1);//此处可修改为quicksort(array,low,w),
                            //但对应的1号标记处要改为array[j]<x,否则有相同数时会陷入死循环
   quicksort(array,w+1,high);
        
    }  
}
 
 
//main function
void main(){
time_t beginMerge,endMerge,beginQuick,endQuick; 
int choose;
cout<<"请输入你要排序的数组的数据来源,1为手工输入,2为随机生成"<<endl;
cin>>choose;
while(choose!=1&&choose!=2){
cout<<"输入有误,请重新输入,1为手工输入,2为随机生成"<<endl;
cin>>choose;
}
switch(choose){
case 1:{
int num;
cout<<"请输入需要排序的数值个数"<<endl;
cin>>num;
 
double *array =new double[num];
cout<<"请输入要排序的数值,范围在0~10^5之间"<<endl;
for(int i=0;i<num;i++){
cin>>array[i];
} 

beginMerge=clock();
mergesort(array,0,num-1);
endMerge=clock();
beginQuick=clock();
quicksort(array,0,num-1);
endQuick=clock();
cout<<"排序:";

for(int z=0;z<num;z++){
cout<<array[z]<<" ";

} 
cout<<endl; 
cout<<"归并排序所用时间: "<<static_cast<double>(endMerge-beginMerge)/CLOCKS_PER_SEC*1000<<"毫秒   快速排序所用时间:"//因为是求毫秒所以乘上1000
<<static_cast<double>(endQuick-beginQuick)/CLOCKS_PER_SEC*1000<<"毫秒"<<endl; 
break;}
case 2:{
for(int v=1;v<=20;v++){
double* array = new double[v*5000];
for(int j=0;j<v*5000;j++){
array[j]=(int)rand()/pow(10,5);
}
beginMerge=clock();
mergesort(array,0,v*5000-1);
endMerge=clock();
beginQuick=clock();
quicksort(array,0,v*5000-1);
endQuick=clock();
cout<<"第"<<v<<"组归并排序所用时间: "<<static_cast<double>(endMerge-beginMerge)/CLOCKS_PER_SEC*1000<<"毫秒   快速排序所用时间:"
<<static_cast<double>(endQuick-beginQuick)/CLOCKS_PER_SEC*1000<<"毫秒"<<endl; 
}
break;}
}
}

有更多作者原创文章在:
http://www.xmxbbs.com/forum.php?mod=viewthread&tid=3242&fromuid=2100
(出处: 湖南新梦想)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值