算法排序问题实验报告.docx

上传人:b****1 文档编号:29139824 上传时间:2023-07-20 格式:DOCX 页数:16 大小:890.28KB
下载 相关 举报
算法排序问题实验报告.docx_第1页
第1页 / 共16页
算法排序问题实验报告.docx_第2页
第2页 / 共16页
算法排序问题实验报告.docx_第3页
第3页 / 共16页
算法排序问题实验报告.docx_第4页
第4页 / 共16页
算法排序问题实验报告.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

算法排序问题实验报告.docx

《算法排序问题实验报告.docx》由会员分享,可在线阅读,更多相关《算法排序问题实验报告.docx(16页珍藏版)》请在冰豆网上搜索。

算法排序问题实验报告.docx

算法排序问题实验报告

《排序问题求解》实验报告

1、算法得基本思想

1、直接插入排序算法思想

 直接插入排序得基本思想就是将一个记录插入到已排好序得序列中,从而得到一个新得,

记录数增 1得有序序列。

直接插入排序算法得伪代码称为InsertionSort,它得参数就是一个数组A[1、、n],包含了n

个待排序得数。

用伪代码表示直接插入排序算法如下:

InsertionSort(A)

fori←2ton

dokey←A[i] //key表示待插入数

//InsertA[i]intothe sortedsequenceA[1、、i-1]

j←i-1

whilej>0andA[j]>key

doA[j+1]←A[j]

j←j-1

A[j+1]←key

2、快速排序算法思想

快速排序算法得基本思想就是,通过一趟排序将待排序序列分割成独立得两部分,其中一

部分记录得关键字均比另一部分记录得关键字小,则可对这两部分记录继续进行排序,以达

到整个序列有序。

  假设待排序序列为数组A[1、、n],首先选取第一个数 A[0],作为枢轴(pivot),然后按照下述原则重新排列其余数:

将所有比A[0]大得数都排在它得位置之前,将所有比A[0]小得数都排在它得位置之后,由此以A[0]最后所在得位置 i作为分界线,将数组 A[1、、n]分成两个子数组A[1、、i-1]与A[i+1、、n]。

这个过程称作一趟快速排序。

通过递归调用快速排序,对子数组A[1、、i-1]与A[i+1、、n]排序。

 一趟快速排序算法得伪代码称为Partition,它得参数就是一个数组 A[1、、n]与两个指针low、high,设枢轴为 pivotkey,则首先从high所指位置起向前搜索,找到第一个小于pivotkey 得数,并将其移到低端,然后从low所指位置起向后搜索,找到第一个大于 pivotkey得数,并将其移到高端,重复这两步直至low=high。

最后,将枢轴移到正确得位置上。

用伪代码表示一趟快速排序算法如下:

Partition(A,low, high)

A[0]←A[low]

//用数组得第一个记录做枢轴记录

privotkey←A[low]

//枢轴记录关键字

whilelow<high//从表得两端交替地向中间扫描

whilelow=privotkeydohigh←high-1

A[low]←A[high]//将比枢轴记录小得记录移到低端

whilelow<high&&A[low]<=pivotkey) dolow←low+1

A[high]←A[low]//将比枢轴记录大得记录移到高端

A[low]←A[0]//枢轴记录到位

return low//返回枢轴位置

2、算法得理论分析

1、直接插入排序算法理论分析

从空间来瞧,直接插入排序只需要一个数得辅助空间;从时间来瞧,直接插入排序得基

本操作为:

比较两个关键字得大小与移动记录。

先分析一趟直接插入排序得情况。

伪代码

InsertionSort 中while 循环得次数取决于待插入得数与前i-1个数之间得关系。

若 A[i]<A[0],则在 while循环中,待插入数需与有序数组 A[1、、i-1]中i-1个数进行比较,并将A[i-1]中i-1个数后移。

则在整个排序过程(进行n-1趟插入排序)中,当待排序数组中数按非递减有序排列时,则需进行数间比较次数达最小值n-1,数不需要移动;反之,当待排序数组中数按非递增有序排列时,总得比较次数达最大值(n+2)(n-1)/2,数移动得次数也达到最大值(n+4)(n-1)/2。

若待排序数组就是随机得,即待排序数组中得数可能出现得各种排序得概率相同,则我们可取

上述最小值与最大值得平均值,作为直接插入排序时所需进行数间得比较次数与数得移动次

数,约为n^2/4。

因此直接插入排序算法,在最佳情况下得时间复杂度就是 O(n),在最坏情况下得时间复杂度为 O(n^2)。

2、 快速排序算法理论分析

下面我们来分析快速排序得平均时间性能。

假设T(n)为对n个记录A[1、、n]进行快速排序所需时间,则由算法 QuickSort 可见:

其中,Tpass(n)为对 n个记录进行一趟快速排序Partition(A,1,n)所需得时间,从一

趟快速排序算法可见,其与记录数n 成正比,可以用cn表示(c为某个常数);T(k-1)与T

(n-k)分别为对A[1、、k-1]与A[k+1、、n]中记录进行快速排序QuickSort(A,1,k-1)与

QuickSort(A,k+1,n)所需时间。

假设待排序列中记录就是随机排列得,则在一趟排序之后,

k取 1至n之间任何一值得概率相同,快速排序所需时间得平均值则为Tavg(n)=knInn,其中n为待排序序列中记录得个数,k为某个常数。

   通常,快速排序被认为就是,在所有同数量级(O(nlogn))得排序方法中,其平均性能最

好。

但就是,若初始记录序列按关键字有序或基本有序时,快速排序将蜕化为起泡排序,其时

间复杂度为 O(n^2)。

3、试验分析

1、试验环境

WIN32系统,VC6、0

2、 程序得执行

1)由函数datagenetare()生成20000个在区间[1,100000]上得随机整数,并将随机整数保存到数组num[],接着调用函数WriteFile()将这些数输出到外部文件data、txt中。

2)调用函数 ReadFile()从data、txt中读取数据,并将其保存到数组 num1[]中。

接着对数组 num1进行直接插入排序,并计算与记录其运行时间。

最后,调用函数WriteFile()将直接插入排序得结果写入resultsIS、txt,并记录运行时间为TimeIS。

3)调用函数 ReadFile()从data、txt中读取数据,并将其保存到数组 num2[]中。

接着对数组num2进行快速排序,并计算与记录其运行时间。

最后,调用函数WriteFile()将快速排序得结果写入resultsQS、txt,并记录运行时间为TimeQS。

3、试验数据

当N=20000时:

当N=30000时:

当N=40000时:

当N=50000时:

当N=60000时:

当N=70000时:

当N=80000时:

4、实验结果分析

2

0

插入排序

0、325

0、719

1、397

2、199

3、05

4、571

5、46

快速排序

0、003

0、005

0、008

0、01

0、012

0、011

0、013

做出折线统计图

4、试验心得

通过本次试验首先对在C++下得文件操作有了一定得深入认识,对于快速排序与插入排序得时间有了相当清晰且一目了然得认识,并且从原理上明白了快速排序得快得原因,对各种排序算法得优劣性有了全局得认识!

5、实验代码

#include<iostream>

#include <ctime>

#include<cstdlib>

#include <fstream>

#include

usingnamespacestd;

constintNumS=80000;

voiddatagenetare(intnum[],intn);//产生随机数,保存到数组num

voidWrite num[],charname[],intn); //输出数组num到data、txt文件

voidReadnum[],charname[]);//读取名为name文件中得数据,保存到数组num

voidQuickSort(intarr[],intn);//将数组arr[]中数据快速排序

void InsertionSort(int arr[],intn);//将数组arr[]中数据直接插入排序

intmain()

{

ﻩint*num=(int*)malloc(sizeof(int)*NumS);

int *num1=(int *)malloc(sizeof(int)*NumS);

ﻩint*num2=(int*)malloc(sizeof(int)*NumS);

ﻩclock_t start_time1,end_time1,start_time2,end_time2;

ﻩdoubletimeQS=0,timeIS=0;

ﻩcout<<"Create"<

ﻩdatagenetare(num,NumS);//产生随机数,保存到数组num

Write,"data、txt",NumS);//输出数组到data、txt文件

ﻩcout、precision(6);//设置浮点数得显示精度

cout、setf(ios_base:

:

showpoint);//输出末尾得

//直接插入排序得分析

Read,"data、txt");//读取data、txt中得数据,保存到数组num1

cout<<"\nInsertionSortStart 、、、、\n";

start_time1=clock();//开始计时

InsertionSort(num1,NumS);//直接插入排序数组num1中得数据

end_time1=clock();//结束计时

timeIS=(double)(end_time1-start_time1)/CLOCKS_PER_SEC;

cout<<"TheTime-suption inInsertionSortis"<<timeIS<<"seconds!

\n\n";//输出运行时间

ﻩﻩWrite,"resultsIS、txt",NumS);//排序后得数据输出到resultQS、txt

ﻩ//输出运行时间timeIS到resultsIS、txt

ofstream ocout;

ﻩocout、open("resultsIS、txt",ios:

:

app);

ﻩif(ocout、good())//打开resultsIS、txt

ﻩﻩocout<<"\nTheTime-suptioninInsertionSort is "<

ﻩocout、close();

ﻩ}

else

{

ﻩﻩcout<<"\nCannotopenresultsIS、txt!

\n";

ﻩexit

(1); //异常退出

ﻩ}

//快速排序得分析

Read,"data、txt"); //读取data、txt中得数据,保存到数组num2[]

ﻩcout<<"QuickSortStart 、、、、、\n";

ﻩstart_time2=clock();//开始计时

ﻩQuickSort(num2,NumS); //快速排序数组num中得数据

end_time2=clock();//结束计时

timeQS=(double)(end_time2-start_time2)/CLOCKS_PER_SEC;

ﻩcout<<"TheTime-suptioninQuickSort is "<

\n";//输出运行时间

Write,"resultsQS、txt",NumS);//排序后得数据输出到resultQS、txt

ﻩ//输出运行时间timeQS到resultsQS、txt

ﻩocout、open("resultsQS、txt",ios:

:

app);

if(ocout、good())//打开resultsIS、txt

ﻩ{

ﻩocout<<"\nTheTime-suptioninQuickSortis "<<timeQS<<" seconds\n";

ocout、close();

ﻩ}

else

{

cout<<"\nCannotopenresultsQS、txt!

\n";

exit

(1);//异常退出

ﻩ}

return0;

}

voiddatagenetare(int*num,intn)

{

ﻩinti;

srand((unsigned)time(0));//srand()种子发生器函数,还有rand()随机数生成器函数

for(i=0;i

ﻩnum[i]=rand()%9999+1;

printf("\n");

}

//将数组中得数据输出到文件

voidWrite *num,charname[],intn)

{

ﻩofstreamocout;

ocout、open(name,ios:

:

trunc);

inti=0;

if(ocout、fail())

exit(1);//打开文件失败,退出

for(;i

{

ﻩocout<

ﻩif((i+1)%40==0||i==n-1)//每输出40个数,换一行

ﻩﻩocout<<"\n";

ocout、close();

}

//将文件中得数据输入到数组

voidRead*num,char name[])

{

ﻩstringstrLine;

inti=0;

charachLine[300];

ﻩconst char*pchTok;

ﻩifstream icin;

icin、open(name,ios:

:

in); //打开名为name得文件

while(icin、good())

ﻩ{

ﻩﻩinti=0;

while(getline(icin,strLine))

ﻩ{

ﻩﻩstrLine、copy(achLine,strLine、size(),0);

ﻩﻩachLine[strLine、size()]='\0';

//每行中得元素以空格为标识断开转换为int类型后存入数组

ﻩﻩpchTok=strtok(achLine,"");

ﻩﻩwhile((pchTok!

=NULL))

ﻩ{

ﻩﻩnum[i]=atoi(pchTok);

ﻩﻩﻩﻩi++;

ﻩﻩﻩpchTok= strtok(NULL, " ");

}

}

icin、close();

}

//快速排序得实现,从左向右递增排序

void QuickSort(int*arr, intn)

{

ﻩint L=0;

intR= n-1;

ﻩintt=arr[L];//区间得第一个数作为基准

ﻩif(n<=1)//数组中存在个或个数据时,函数返回

ﻩreturn;

ﻩ//将数据分成两个区间

while(L<R){//区间内至少存在一个元素得情况

while(L<R&&t<=arr[R])R--;//从右向左搜索,直到第一个小于t得数arr[R]

ﻩarr[L]=arr[R];

ﻩwhile(L<R&&arr[L]<=t)L++;//从左向右搜索,找到第一个大于t得数arr[L]

ﻩarr[R]=arr[L];

ﻩ}

ﻩarr[L]=t;

QuickSort(arr,L);//对左区间递归排序

QuickSort(arr+L+1,n-L-1);//对右区间递归排序

}

//直接插入排序得实现,从左向右递增排序

void InsertionSort(int*arr,int n)

{

ﻩinti=0,temp=0,j=0;

ﻩif(n<=1)

ﻩreturn;

ﻩfor(i=1;i

{

ﻩﻩtemp=arr[i];//temp记录要插入得数据arr[i]

j=i;//要插入得数据得位置

ﻩﻩfor(;j>0&&arr[j-1]>temp;--j)//将a[i]插入到已排序得arr[0]~arr[i-1]中

ﻩ{

arr[j]=arr[j-1];//比temp大得数据依次后移

ﻩ}

ﻩﻩarr[j]=temp;//找到第一个不大于于temp得数据,在j处插入arr[i]

ﻩ}

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1