数据结构实验八:快速排序
数据结构实验报告八-快速排序

实验8 快速排序1.需求分析(1)输入的形式和输入值的范围:第一行是一个整数n,代表任务的件数。
接下来一行,有n个正整数,代表每件任务所用的时间。
中间用空格或者回车隔开。
不对非法输入做处理,及假设用户输入都是合法的。
(2)输出的形式:输出有n行,每行一个正整数,从第一行到最后一行依次代表着操作系统要处理的任务所用的时间。
按此顺序进行,则使得所有任务等待时间最小。
(3)程序所能达到的功能:在操作系统中,当有n 件任务同时来临时,每件任务需要用时ni,输出所有任务等待的时间和最小的任务处理顺序。
(4)测试数据:输入请输入任务个数:9请输入任务用时:5 3 4 2 6 1 5 7 3输出任务执行的顺序:1 2 3 3 4 5 5 6 72.概要设计(1)抽象数据类型的定义:为实现上述程序的功能,应以整数存储用户的第一个输入。
并将随后输入的一组数据储存在整数数组中。
(2)算法的基本思想:如果将任务按完成时间从小到大排序,则在完成前一项任务时后面任务等待的时间总和最小,即得到最小的任务处理顺序。
采取对输入的任务时间进行快速排序的方法可以在相对较小的时间复杂度下得到从小到大的顺序序列。
3.详细设计(1)实现概要设计中定义的所有数据类型:第一次输入的正整数要求大于零,为了能够存储,采用int型定义变量。
接下来输入的一组整数,数据范围大于零,为了排序需要,采用线性结构存储,即int类型的数组。
(2)实现程序的具体步骤:一.程序主要采取快速排序的方法处理无序数列:1.在序列中根据随机数确定轴值,根据轴值将序列划分为比轴值小和比轴值大的两个子序列。
2.对每个子序列采取从左右两边向中间搜索的方式,不断将值与轴值比较,如果左边的值大于轴值而右边的小于轴值则将二者交换,直到左右交叉。
3.分别对处理完毕的两个子序列递归地采取1,2步的操作,直到子序列中只有一个元素。
二.程序各模块的伪代码:1、主函数int main(){int n;cout<<"请输入任务个数:";cin>>n;int a[n];cout<<"请输入任务用时:";for(int i=0;i<n;i++) cin>>a[i];qsort(a,0,n-1); //调用“快排函数”cout<<"任务执行的顺序:";for(int i=0;i<n;i++) cout<<a[i]<<" "; //输出排序结果}2、快速排序算法:void qsort(int a[],int i,int j){if(j<=i)return; //只有一个元素int pivotindex=findpivot(a,i,j); //调用“轴值寻找函数”确定轴值swap(a,pivotindex,j); //调用“交换函数”将轴值置末int k=partition(a,i-1,j,a[j]); //调用“分割函数”根据轴值分割序列swap(a,k,j);qsort(a,i,k-1); //递归调用,实现子序列的调序qsort(a,k+1,j);}3、轴值寻找算法://为了保证轴值的“随机性”,采用时间初始化种子。
数据结构实验八 排序

实验八排序一、实验目的1、掌握常用的排序方法,如归并排序、快速排序等。
2、深刻理解排序的定义和排序方法的特点,并能加以灵活应用。
3、能够分析各种算法的效率和适用条件。
二、实验要求1、认真阅读程序。
2、上机调试,并运行程序。
3、保存和截图程序的运行结果,并结合程序进行分析。
三、实验内容和基本原理1、实验8.1 归并排序的实现已知关键字序列为{1,8,6,4,10,5,3,2,22},请对此序列进行归并排序,并输出结果。
见参考程序8.1。
2、实验8.2快速排序的实现快速排序是通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
见参考程序8.2。
参考程序8.1归并排序#include"stdio.h"int num=0;void print_data(int data[],int first,int last){int i=0;for(i=0;i<first;i++)printf("*");for(i=first;i<=last;i++)printf("%3d",data[i]);for(i=last;i<=8;i++)printf("*");printf("\n");}void merge(int array[],int first,int last)/*一趟归并*/{int mid,i1,i2,i3;int temp[10];int i,j;mid=(first+last)/2;i1=0;i2=first;i3=mid+1;while(i2<=mid&&i3<=last){if(array[i2]<array[i3])temp[i1++]=array[i2++];elsetemp[i1++]=array[i3++];}if(i2<=mid)while(i2<=mid)temp[i1++]=array[i2++];if(i3<=last)while(i3<=last)temp[i1++]=array[i3++];for(i=first,j=0;i<=last;i++,j++)array[i]=temp[j];print_data(array,first,last);}void mergesort(int data[],int first,int last)/*归并排序*/{int mid;if(first<last){mid=(first+last)/2;mergesort(data,first,mid);mergesort(data,mid+1,last);print_data(data,first,last);merge(data,first,last);}}void main(){int a[]={1,8,6,4,10,5,3,2,22};/*可根据实际情况初始化*/ mergesort(a,0,8);}参考程序8.2快速排序#include<iostream.h>#include"stdio.h"#define MAX 8int QuickSort(int a[],int l,int r){int pivot;//枢轴int i=l;int j=r;int tmp;pivot=a[(l+r)/2];//取数组中间的数为枢轴do{while(a[i]<pivot)i++;//i右移while(a[j]>pivot)j--;//j左移if(i<=j){tmp=a[i];a[i]=a[j];a[j]=tmp;//交换a[i]和a[j]i++;j--;}}while(i<=j);if(l<j)QuickSort(a,l,j);if (i<r)QuickSort(a,i,r);return 1; }/*********************************************/ int main(){ int array[MAX];int i;printf("请输入%d个整数:",MAX);for (i=0;i<MAX;i++)scanf("%d",&array[i]);QuickSort(array,0,MAX-1);printf("快速排序后:");for (i=0;i<MAX;i++)printf("%d ",array[i]);printf("\n");return 0;}四、实验验证与练习1、设给定的排序码序列为(72,73,71,23,94,16,05,68),请写出归并排序和快速排序过程中每趟排序的结果。
排序的实验报告范文

排序的实验报告范文数据结构实验报告实验名称:实验四排序学生姓名:班级:班内序号:学号:日期:2022年12月21日实验要求题目2使用链表实现下面各种排序算法,并进行比较。
排序算法:1、插入排序2、冒泡排序3、快速排序4、简单选择排序5、其他要求:1、测试数据分成三类:正序、逆序、随机数据。
2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。
3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)。
4、对2和3的结果进行分析,验证上述各种算法的时间复杂度。
编写测试main()函数测试线性表的正确性。
2、程序分析2.1存储结构说明:本程序排序序列的存储由链表来完成。
其存储结构如下图所示。
(1)单链表存储结构:结点地址:1000HA[2]结点地址:1000H1080H……头指针地址:1020HA[0]头指针地址:1020H10C0H……地址:1080HA[3]地址:1080HNULL……地址:10C0HA[1]地址:10C0H1000H……(2)结点结构tructNode{intdata;Node某ne某t;};示意图:intdataNode某ne某tintdataNode某ne某t2.2关键算法分析一:关键算法(一)直接插入排序voidLinkSort::InertSort()直接插入排序是插入排序中最简单的排序方法,其基本思想是:依次将待排序序列中的每一个记录插入到一个已排好的序列中,直到全部记录都排好序。
(1)算法自然语言1.将整个待排序的记录序列划分成有序区和无序区,初始时有序区为待排序记录序列中的第一个记录,无序区包括所有剩余待排序的记录;2.将无须去的第一个记录插入到有序区的合适位置中,从而使无序区减少一个记录,有序区增加一个记录;3.重复执行2,直到无序区中没有记录为止。
(2)源代码voidLinkSort::InertSort()//从第二个元素开始,寻找前面那个比它大的{Node某P=front->ne某t;//要插入的节点的前驱while(P->ne某t){Node某S=front;//用来比较的节点的前驱while(1){if(P->ne某t->data<S->ne某t->data)//P的后继比S的后继小则插入{inert(P,S);break;}S=S->ne某t;if(S==P)//若一趟比较结束,且不需要插入{P=P->ne某t;break;}}}}(3)时间和空间复杂度最好情况下,待排序序列为正序,时间复杂度为O(n)。
实验报告-排序与查找

电子科技大学实验报告课程名称:数据结构与算法学生姓名:学号:点名序号:指导教师:实验地点:基础实验大楼实验时间: 5月20日2014-2015-2学期信息与软件工程学院实验报告(二)学生姓名学号:指导教师:实验地点:基础实验大楼实验时间:5月20日一、实验室名称:软件实验室二、实验项目名称:数据结构与算法—排序与查找三、实验学时:4四、实验原理:快速排序的基本思想是:通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要小,然后再按次方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
假设要排序的数组是A[1]……A[N],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一躺快速排序。
一躺快速排序的算法是:1)设置两个变量I、J,排序开始的时候I:=1,J:=N2)以第一个数组元素作为关键数据,赋值给X,即X:=A[1];3)从J开始向前搜索,即(J:=J-1),找到第一个小于X的值,两者交换;4)从I开始向后搜索,即(I:=I+1),找到第一个大于X的值,两者交换;5)重复第3、4步,直到I=J。
二分法查找(折半查找)的基本思想:(1)确定该区间的中点位置:mid=(low+high)/2min代表区间中间的结点的位置,low代表区间最左结点位置,high代表区间最右结点位置(2)将待查a值与结点mid的关键字(下面用R[mid].key)比较,若相等,则查找成功,否则确定新的查找区间:A)如果R[mid].key>a,则由表的有序性可知,R[mid].key右侧的值都大于a,所以等于a的关键字如果存在,必然在R[mid].key左边的表中,这时high=mid-1;B)如果R[mid].key<a,则等于a的关键字如果存在,必然在R[mid].key右边的表中。
数据结构实验报告——排序

1.实验要求【实验目的】学习、实现、对比各种排序算法,掌握各种排序算法的优劣,以及各种算法使用的情况。
【实验内容】使用简单数组实现下面各种排序算法,并进行比较。
排序算法:1、插入排序2、希尔排序3、冒泡排序4、快速排序5、简单选择排序6、堆排序(选作)7、归并排序(选作)8、基数排序(选作)9、其他要求:1、测试数据分成三类:正序、逆序、随机数据2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。
3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)4、对2和3的结果进行分析,验证上述各种算法的时间复杂度编写测试main()函数测试线性表的正确性。
2. 程序分析2.1 存储结构存储结构:数组2.2 关键算法分析//插入排序void InsertSort(int r[], int n) {int count1=0,count2=0;插入到合适位置for (int i=2; i<n; i++){r[0]=r[i]; //设置哨兵for (int j=i-1; r[0]<r[j]; j--) //寻找插入位置r[j+1]=r[j]; //记录后移r[j+1]=r[0];count1++;count2++;}for(int k=1;k<n;k++)cout<<r[k]<<" ";cout<<endl;cout<<"比较次数为"<<count1<<" 移动次数为"<<count2<<endl; }//希尔排序void ShellSort(int r[], int n){int i;int d;int j;int count1=0,count2=0;for (d=n/2; d>=1; d=d/2) //以增量为d进行直接插入排序{for (i=d+1; i<n; i++){r[0]=r[i]; //暂存被插入记录for (j=i-d; j>0 && r[0]<r[j]; j=j-d)r[j+d]=r[j]; //记录后移d个位置r[j+d]=r[0];count1++;count2=count2+d;}count1++;}for(i=1;i<n;i++)cout<<r[i]<<" ";cout<<endl;cout<<"比较次数为"<<count1<<" 移动次数为"<<count2<<endl; }//起泡排序void BubbleSort(int r[], int n) {插入到合适位置int temp;int exchange;int bound;int count1=0,count2=0;exchange=n-1; //第一趟起泡排序的范围是r[1]到r[n]while (exchange) //仅当上一趟排序有记录交换才进行本趟排序{bound=exchange;exchange=0;for(int j=0;j<bound;j++) //一趟起泡排序{count1++; //接下来有一次比较if(r[j]>r[j+1]){temp=r[j]; //交换r[j]和r[j+1]r[j]=r[j+1];r[j+1]=temp;exchange=j; //记录每一次发生记录交换的位置count2=count2+3; //移动了3次}}}for(int i=1;i<n;i++)cout<<r[i]<<" ";cout<<endl;cout<<"比较次数为"<<count1<<" 移动次数为"<<count2<<endl;}//快速排序一次划分int Partition(int r[], int first, int end,int &count1,int &count2){int i=first; //初始化int j=end;while (i<j){while (i<j && r[i]<= r[j]){j--; //右侧扫描count1++;}count1++;if (i<j){temp=r[i]; //将较小记录交换到前面r[i]=r[j];r[j]=temp;i++;count2=count2+3;}while (i<j && r[i]<= r[j]){i++; //左侧扫描count1++;}count1++;if (i<j){temp=r[j];r[j]=r[i];r[i]=temp; //将较大记录交换到后面j--;count2=count2+3;}}return i; //i为轴值记录的最终位置}//快速排序void QuickSort(int r[], int first, int end,int &count1,int &count2){if (first<end){ //递归结束int pivot=Partition(r, first, end,count1,count2); //一次划分QuickSort(r, first, pivot-1,count1,count2);//递归地对左侧子序列进行快速排序QuickSort(r, pivot+1, end,count1,count2); //递归地对右侧子序列进行快速排序}}//简单选择排序Array void SelectSort(int r[ ], int n){int i;int j;int index;int temp;int count1=0,count2=0;for (i=0; i<n-1; i++) //对n个记录进行n-1趟简单选择排序{index=i;for(j=i+1;j<n;j++) //在无序区中选取最小记录{count1++; //比较次数加一if(r[j]<r[index]) //如果该元素比现在第i个位置的元素小index=j;}count1++; //在判断不满足循环条件j<n时,比较了一次if(index!=i){temp=r[i]; //将无序区的最小记录与第i个位置上的记录交换r[i]=r[index];r[index]=temp;count2=count2+3; //移动次数加3 }}for(i=1;i<n;i++)cout<<r[i]<<" ";cout<<endl;cout<<"比较次数为"<<count1<<" 移动次数为"<<count2<<endl;}//筛选法调整堆void Sift(int r[],int k,int m,int &count1,int &count2) //s,t分别为比较和移动次数{int i;int j;int temp;i=k;j=2*i+1; //置i为要筛的结点,j为i的左孩子while(j<=m) //筛选还没有进行到叶子{if(j<m && r[j]<r[j+1]) j++; //比较i的左右孩子,j为较大者count1=count1+2; //该语句之前和之后分别有一次比较if(r[i]>r[j])break; //根结点已经大于左右孩子中的较大者else{temp=r[i];r[i]=r[j];r[j]=temp; //将根结点与结点j交换i=j;j=2*i+1; //下一个被筛结点位于原来结点j的位置count2=count2+3; //移动次数加3 }}}//堆排序void HeapSort(int r[],int n){int count1=0,count2=0; //计数器,计比较和移动次数int i;int temp;for(i=n/2;i>=0;i--) //初始建堆,从最后一个非终端结点至根结点Sift(r,i,n,count1,count2) ;for(i=n-1; i>0; i--) //重复执行移走堆顶及重建堆的操作{temp=r[i]; //将堆顶元素与最后一个元素交换r[i]=r[0];r[0]=temp; //完成一趟排序,输出记录的次序状态Sift(r,0,i-1,count1,count2); //重建堆}for(i=1;i<n;i++)cout<<r[i]<<" ";cout<<endl;cout<<"比较次数为"<<count1<<" 移动次数为"<<count2<<endl;}//一次归并void Merge(int r[], int r1[], int s, int m, int t){int i=s;int j=m+1;int k=s;while (i<=m && j<=t){if (r[i]<=r[j])r1[k++]=r[i++]; //取r[i]和r[j]中较小者放入r1[k]elser1[k++]=r[j++];}if (i<=m)while (i<=m) //若第一个子序列没处理完,则进行收尾处理r1[k++]=r[i++];elsewhile (j<=t) //若第二个子序列没处理完,则进行收尾处理r1[k++]=r[j++];}//一趟归并void MergePass(int r[ ], int r1[ ], int n, int h){int i=0;int k;while (i<=n-2*h) //待归并记录至少有两个长度为h的子序列{Merge(r, r1, i, i+h-1, i+2*h-1);i+=2*h;}if (i<n-h)Merge(r, r1, i, i+h-1, n); //待归并序列中有一个长度小于h else for (k=i; k<=n; k++) //待归并序列中只剩一个子序列r1[k]=r[k];}//归并排序void MergeSort(int r[ ], int r1[ ], int n ){int h=1;int i;while (h<n){MergePass(r, r1, n-1, h); //归并h=2*h;MergePass(r1, r, n-1, h);h=2*h;}for(i=1;i<n;i++)cout<<r[i]<<" ";cout<<endl;}void Newarray(int a[],int b[],int c[]) {cout<<"新随机数组:";c[0]=0;a[0]=0;b[0]=0;for(int s=1;s<11;s++){a[s]=s;b[s]=20-s;c[s]=rand()%50+1;cout<<c[s]<<" ";}cout<<endl;}2.3 其他3. 程序运行结果void main(){srand(time(NULL));const int num=11; //赋值int a[num];int b[num];int c[num];int c1[num];c[0]=0;a[0]=0;b[0]=0;Newarray(a,b,c);cout<<"顺序数组:";for(int j=1;j<num;j++)cout<<a[j]<<" ";cout<<endl;cout<<"逆序数组:";for(j=1;j<num;j++)cout<<b[j]<<" ";cout<<endl;cout<<endl;cout<<"插入排序结果为:"<<"\n";InsertSort(a,num);InsertSort(b,num);InsertSort(c,num);cout<<endl;Newarray(a,b,c);cout<<"希尔排序结果为:"<<"\n";ShellSort(a, num);ShellSort(b, num);ShellSort(c, num);cout<<endl;Newarray(a,b,c);cout<<"起泡排序结果为:"<<"\n";BubbleSort(a, num);BubbleSort(b, num);BubbleSort(c, num);cout<<endl;int count1=0,count2=0;Newarray(a,b,c);cout<<"快速排序结果为:"<<"\n";QuickSort(a,0,num-1,count1,count2);for(int i=1;i<num;i++)cout<<a[i]<<" ";cout<<endl;cout<<"比较次数为"<<count1<<" 移动次数为"<<count2<<endl; count1=0,count2=0;QuickSort(b,0,num-1,count1,count2);for(i=1;i<num;i++)cout<<b[i]<<" ";cout<<endl;cout<<"比较次数为"<<count1<<" 移动次数为"<<count2<<endl; count1=0,count2=0;QuickSort(c,0,num-1,count1,count2);for(i=1;i<num;i++)cout<<c[i]<<" ";cout<<endl;cout<<"比较次数为"<<count1<<" 移动次数为"<<count2<<endl;cout<<endl;cout<<endl;Newarray(a,b,c);cout << "简单选择排序结果为:" << "\n";SelectSort(a,num);SelectSort(b,num);SelectSort(c,num);cout<<endl;Newarray(a,b,c);cout << "堆排序结果为:" << "\n";HeapSort(a, num);HeapSort(b, num);HeapSort(c, num);cout<<endl;Newarray(a,b,c);cout << "归并排序结果为:" << "\n";MergeSort(a, c1,num );MergeSort(b, c1,num );MergeSort(c, c1,num );}。
数据结构实验报告-排序

数据结构实验报告-排序一、实验目的本实验旨在探究不同的排序算法在处理大数据量时的效率和性能表现,并对比它们的优缺点。
二、实验内容本次实验共选择了三种常见的排序算法:冒泡排序、快速排序和归并排序。
三个算法将在同一组随机生成的数据集上进行排序,并记录其性能指标,包括排序时间和所占用的内存空间。
三、实验步骤1. 数据的生成在实验开始前,首先生成一组随机数据作为排序的输入。
定义一个具有大数据量的数组,并随机生成一组在指定范围内的整数,用于后续排序算法的比较。
2. 冒泡排序冒泡排序是一种简单直观的排序算法。
其基本思想是从待排序的数据序列中逐个比较相邻元素的大小,并依次交换,从而将最大(或最小)的元素冒泡到序列的末尾。
重复该过程直到所有数据排序完成。
3. 快速排序快速排序是一种分治策略的排序算法,效率较高。
它将待排序的序列划分成两个子序列,其中一个子序列的所有元素都小于等于另一个子序列的所有元素。
然后对两个子序列分别递归地进行快速排序。
4. 归并排序归并排序是一种稳定的排序算法,使用分治策略将序列拆分成较小的子序列,然后递归地对子序列进行排序,最后再将子序列合并成有序的输出序列。
归并排序相对于其他算法的优势在于其稳定性和对大数据量的高效处理。
四、实验结果经过多次实验,我们得到了以下结果:1. 冒泡排序在数据量较小时,冒泡排序表现良好,但随着数据规模的增大,其性能明显下降。
排序时间随数据量的增长呈平方级别增加。
2. 快速排序相比冒泡排序,快速排序在大数据量下的表现更佳。
它的排序时间线性增长,且具有较低的内存占用。
3. 归并排序归并排序在各种数据规模下都有较好的表现。
它的排序时间与数据量呈对数级别增长,且对内存的使用相对较高。
五、实验分析根据实验结果,我们可以得出以下结论:1. 冒泡排序适用于数据较小的排序任务,但面对大数据量时表现较差,不推荐用于处理大规模数据。
2. 快速排序是一种高效的排序算法,适用于各种数据规模。
快速排序实验总结

快速排序实验总结快速排序是一种常用的排序算法,其基本思想是通过分治的方法将待排序的序列分成两部分,其中一部分的所有元素均小于另一部分的元素,然后对这两部分分别进行递归排序,直到整个序列有序。
下面是我在实验中对于快速排序算法的一些总结和思考。
一、算法步骤快速排序的基本步骤如下:1.选择一个基准元素(pivot),将序列分成两部分,一部分的所有元素均小于基准元素,另一部分的所有元素均大于等于基准元素。
2.对于小于基准元素的部分和大于等于基准元素的部分,分别递归地进行快速排序,直到两部分都有序。
3.合并两部分,得到完整的排序序列。
二、算法优缺点优点:1.快速排序的平均时间复杂度为O(nlogn),在排序大数据集时表现优秀。
2.快速排序是一种原地排序算法,不需要额外的空间,因此空间复杂度为O(logn)。
3.快速排序具有较好的可读性和可维护性,易于实现和理解。
缺点:1.快速排序在最坏情况下的时间复杂度为O(n^2),此时需要选择一个不好的基准元素,例如重复元素较多的序列。
2.快速排序在处理重复元素较多的序列时,会出现不平衡的分割,导致性能下降。
3.快速排序在递归过程中需要保存大量的递归栈,可能导致栈溢出问题。
三、算法实现细节在实现快速排序时,以下是一些需要注意的细节:1.选择基准元素的方法:通常采用随机选择基准元素的方法,可以避免最坏情况的出现。
另外,也可以选择第一个元素、最后一个元素、中间元素等作为基准元素。
2.分割方法:可以采用多种方法进行分割,例如通过双指针法、快速选择算法等。
其中双指针法是一种常用的方法,通过两个指针分别从序列的两端开始扫描,交换元素直到两个指针相遇。
3.递归深度的控制:为了避免递归过深导致栈溢出问题,可以设置一个递归深度的阈值,当递归深度超过该阈值时,转而使用迭代的方式进行排序。
4.优化技巧:在实现快速排序时,可以使用一些优化技巧来提高性能。
例如使用三数取中法来选择基准元素,可以减少最坏情况的出现概率;在递归过程中使用尾递归优化技术,可以减少递归栈的使用等。
快速排序算法实验报告

快速排序算法实验报告快速排序算法实验报告引言快速排序算法是一种高效的排序算法,它的时间复杂度为O(nlogn),在实际应用中被广泛使用。
本实验旨在通过实际的实验数据,验证快速排序算法的效果和性能,并对其进行分析和总结。
实验设计本实验采用C++语言编写快速排序算法,并通过随机生成的数据进行排序实验。
实验中使用了不同规模的数据集,并记录了排序所需的时间和比较次数。
实验步骤1. 实现快速排序算法快速排序算法的核心思想是通过选取一个基准元素,将待排序的序列分为两部分,一部分比基准元素小,一部分比基准元素大,然后对这两部分继续进行快速排序。
具体实现时,可以选择序列的第一个元素作为基准元素,然后使用分治法递归地对子序列进行排序。
2. 生成测试数据为了验证快速排序算法的性能,我们生成了不同规模的随机数序列作为测试数据。
测试数据的规模分别为1000、10000、100000和1000000。
3. 进行排序实验使用生成的测试数据,对快速排序算法进行实验。
记录每次排序所需的时间和比较次数,并将结果进行统计和分析。
实验结果通过对不同规模的数据集进行排序实验,我们得到了以下结果:数据规模排序时间(ms)比较次数1000 2 872810000 12 114846100000 124 13564771000000 1483 15737267分析与讨论从实验结果可以看出,随着数据规模的增大,排序所需的时间和比较次数也呈指数级增长。
这符合快速排序算法的时间复杂度为O(nlogn)的特性。
另外,通过观察实验结果,我们可以发现快速排序算法的性能受到多个因素的影响。
首先,基准元素的选择对算法的效率有很大的影响。
如果选择的基准元素恰好是序列的中位数,那么排序的效率会更高。
其次,数据的初始顺序也会影响排序的效果。
如果数据已经是有序的,那么快速排序算法的效率将大大降低。
此外,快速排序算法还存在一些优化的空间。
例如,可以通过随机选择基准元素来避免最坏情况的发生。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
HUNAN UNIVERSITY课程实验报告题目:快速排序学生姓名学生学号专业班级指导老师李晓鸿完成日期 2 0 1 5年1月7日一、需求分析1.程序的功能由用户输入任务件数和任务时间,使用快速排序,输出使得所有任务等待时间最小的序列。
2.输入的形式本程序由用户输入任务总数以及每个任务所花时间,中间用空格或换行隔开,任务总数必须为正整数。
请输入任务总数:请输入各个任务所花时间:3.输出形式在对这些任务所花时间进行快速排序后,将这些数据从小到大输出任务时间。
任务所花时间的排序如下:4.测试数据1.请输入任务总数:9请输入各个任务所花时间:5 3 4 26 1 57 3任务所花时间从小到大的排序如下:1233455672.请输入任务总数:10请输入各个任务所花时间:6 5 1 2 3 5 4 8 6 1任务所花时间从小到大的排序如下:1 12345 56 6 83.请输入任务总数:6请输入各个任务所花时间:10 10 19 45 23 5任务所花时间从小到大的排序如下:5 10 10 19 23 454.请输入任务总数:8请输入各个任务所花时间:8 7 6 5 4 3 2 1任务所花时间从小到大的排序如下: 1 2 3 4 5 6 7 85.请输入任务总数:10请输入各个任务所花时间:2 4 6 8 1 0 12 14 26 15任务所花时间从小到大的排序如下:0 1 2 4 6 8 12 14 15 26二、概要设计1.抽象数据类型将每一个元素储存在一个有序并且有限的序列中,每一个元素都有一个自己的位置,也都有一个数据类型,所以使用线性表来储存各个任务所花的时间。
2.ADTADT alist{数据对象:定义线性表的最大储存元素maxsize;当前储存元素数listsize;数据关系:若listsize=0,则线性表没有元素,为空;基本操作:alist(int n)//构造函数~alist()//析构函数bool append(int a)//增加元素}3.算法的基本思想设要排序的线性表中元素是A[0]……A[N-1],首先通过时间函数余作为关键数据piot,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,通过前后指针的移动,实现快速排序。
再将piot值左右两边的线性表进行快速排序,直到需要快速排序的线性表只有1个元素。
4.程序基本流程程序分为三个模块:输入模块:由用户读入任务总数n以及各个任务所花时间;排序模块:对这些时间进行快速排序;输出模块:输出排序后的序列。
三.详细设计1.物理数据类型由于线性表长度已知,并且进行大量的交换操作,所以使用顺序表来实现。
顺序表的伪代码class alist{public:int maxsize;int listsize;int* listarry;alist(int n){maxsize = n;listsize = 0;listarry = new int[maxsize];}~alist(){delete[]listarry;}bool append(int a){if (listsize == maxsize)return false;listarry[listsize++] = a;return true;}};2.详细设计获取piot值——partation——quicksort获取piot值:获取随机数,通过随机数获得piot值。
为了防止随机数大于所有数,对随机数就行求余,对求余后的值加1(防止左边界为0,右边界为1的情况,(r+l)/2==0).int findpiot(int a, int b){srand(time(0));int n = rand() % ((a+b)/2+1);return n;}partation(划分):开始参数l.r紧挨要分割子线性表的实际边界。
每一轮执行外层do循环时,l和r都将向的线性表中间移动,若在移动过程中,l遇到比piot值大的值就停止,l遇到比piot小的就停止,交换l和r所对应的值,再次移动,直到它们交叉为止。
int partition(int l, int r, int &pivot){do{while (listarry[++l]< pivot);while ((r != 0) && (listarry[--r]> pivot));swap( l, r);} while (l < r);swap( l, r);return l;}quicksort(快速排序):通过递归,获取piot值后,对线性表从位置i到位置j进行一次划分,通过k值获得排序后poit值所在位置,对起始位置i到k和k+1到末尾j再次快速排序。
void qsort( int i, int j){if (j <= i)return;int pivotindex = findpiot( i, j);int k = partition(i - 1, j, listarry[j]);swap( k, j);qsort( i, k - 1);qsort( k + 1, j);}3.算法的时空分析及改进设想最好情况O(nlogn),最差情况(n^2)4.输入和输出的格式输入:输入任务数量,任务时间:请输入任务数: .....请输入任务时间: ......cout <<"输入任务数\n";cin >> n;alist a(n);cout <<"输入任务时间\n";for (int i = 0; i < n; i++){cin >> temp;a.append(temp);}输出:任务所花时间排序如下:.........cout <<"任务所花时间排序如下\n";for (int i = 0; i < n; i++)cout << a.listarry[i] <<"";cout << endl;四.测试结果测试1测试2测试3测试4测试5五.试验心得书上快速排序十分详细,用抽象数据类型做也就多了定义类。
六.附录#include"iostream"#include"time.h"using namespace std;class alist{public:int maxsize;int listsize;int* listarry;alist(int n){maxsize = n;listsize = 0;listarry = new int[maxsize];}~alist(){delete[]listarry;}bool append(int a){if (listsize == maxsize)return false;listarry[listsize++] = a;return true;}int findpiot(int a, int b){srand(time(0));int n = rand() % ((a+b)/2);return n;}int partition(int l, int r, int &pivot){do{while (listarry[++l]< pivot);while ((r != 0) && (listarry[--r]> pivot));swap( l, r);} while (l < r);swap( l, r);return l;}void qsort( int i, int j){if (j <= i)return;int pivotindex = findpiot( i, j);int k = partition(i - 1, j, listarry[j]);swap( k, j);qsort( i, k - 1);qsort( k + 1, j);}void swap( int a, int b){int temp;temp = listarry[a];listarry[a] = listarry[b];listarry[b] = temp;}};int main(){int n,temp;cout <<"输入任务数\n";cin >> n;alist a(n);cout <<"输入任务时间\n";for (int i = 0; i < n; i++){cin >> temp;a.append(temp);}cout << endl;a.qsort(0, n - 1);cout <<"任务所花时间排序如下\n";for (int i = 0; i < n; i++)cout << a.listarry[i] <<"";cout << endl;system("pause");return 0;}。