数据结构各种排序实验报告

合集下载

排序的实验报告范文

排序的实验报告范文

排序的实验报告范文数据结构实验报告实验名称:实验四排序学生姓名:班级:班内序号:学号:日期: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)。

数据结构排序实验报告

数据结构排序实验报告

数据结构排序实验报告数据结构排序实验报告引言:数据结构是计算机科学中的重要概念之一,它涉及到数据的组织、存储和操作方式。

排序是数据结构中的基本操作之一,它可以将一组无序的数据按照特定的规则进行排列,从而方便后续的查找和处理。

本实验旨在通过对不同排序算法的实验比较,探讨它们的性能差异和适用场景。

一、实验目的本实验的主要目的是通过实际操作,深入理解不同排序算法的原理和实现方式,并通过对比它们的性能差异,选取合适的排序算法用于不同场景中。

二、实验环境和工具实验环境:Windows 10 操作系统开发工具:Visual Studio 2019编程语言:C++三、实验过程1. 实验准备在开始实验之前,我们需要先准备一组待排序的数据。

为了保证实验的公正性,我们选择了一组包含10000个随机整数的数据集。

这些数据将被用于对比各种排序算法的性能。

2. 实验步骤我们选择了常见的五种排序算法进行实验比较,分别是冒泡排序、选择排序、插入排序、快速排序和归并排序。

- 冒泡排序:该算法通过不断比较相邻元素的大小,将较大的元素逐渐“冒泡”到数组的末尾。

实现时,我们使用了双重循环来遍历整个数组,并通过交换元素的方式进行排序。

- 选择排序:该算法通过不断选择数组中的最小元素,并将其放置在已排序部分的末尾。

实现时,我们使用了双重循环来遍历整个数组,并通过交换元素的方式进行排序。

- 插入排序:该算法将数组分为已排序和未排序两部分,然后逐个将未排序部分的元素插入到已排序部分的合适位置。

实现时,我们使用了循环和条件判断来找到插入位置,并通过移动元素的方式进行排序。

- 快速排序:该算法通过选取一个基准元素,将数组分为两个子数组,并对子数组进行递归排序。

实现时,我们使用了递归和分治的思想,将数组不断划分为更小的子数组进行排序。

- 归并排序:该算法通过将数组递归地划分为更小的子数组,并将子数组进行合并排序。

实现时,我们使用了递归和分治的思想,将数组不断划分为更小的子数组进行排序,然后再将子数组合并起来。

数据结构实验报告——排序

数据结构实验报告——排序

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. 引言数据结构是计算机科学中的重要概念,它涉及组织和管理数据的方式。

排序算法是数据结构中的重要部分,它可以将一组无序的数据按照一定的规则进行重新排列,以便更容易进行搜索和查找。

在本实验中,我们将对不同的排序算法进行研究和实验,并对其性能进行评估。

2. 实验目的本实验旨在通过比较不同排序算法的性能,深入了解各算法的特点,从而选择最适合特定场景的排序算法。

3. 实验方法本实验使用C++编程语言实现了以下排序算法:冒泡排序、选择排序、插入排序、快速排序和归并排序。

为了评估这些算法的性能,我们设计了一组实验来测试它们在不同数据规模下的排序时间。

4. 实验过程4.1 数据生成首先,我们生成了一组随机的整数数据作为排序的输入。

数据规模从小到大递增,以便观察不同算法在不同规模下的性能差异。

4.2 排序算法实现接下来,我们根据实验要求,使用C++编程语言实现了冒泡排序、选择排序、插入排序、快速排序和归并排序。

每个算法被实现为一个独立的函数,并按照实验顺序被调用。

4.3 性能评估我们使用计时器函数来测量每个排序算法的执行时间。

在测试过程中,我们多次运行每个算法,取平均值以减小误差。

5. 实验结果我们将在不同数据规模下运行每个排序算法,并记录它们的执行时间。

下表展示了我们的实验结果:数据规模(n)冒泡排序选择排序插入排序快速排序归并排序1000 2ms 3ms 1ms 1ms 1ms5000 20ms 15ms 10ms 3ms 5ms10000 85ms 60ms 30ms 5ms 10ms50000 2150ms 1500ms 700ms 10ms 15ms从上表我们可以观察到,随着数据规模的增加,冒泡排序和选择排序的执行时间呈指数级增长,而插入排序、快速排序和归并排序的执行时间则相对较稳定。

此外,当数据规模较大时,快速排序和归并排序的性能远优于其他排序算法。

6. 实验结论根据实验结果,我们可以得出以下结论:- 冒泡排序和选择排序是简单但效率较低的排序算法,仅适用于较小规模的数据排序。

数据结构排序实验报告

数据结构排序实验报告

数据结构排序实验报告数据结构排序实验报告实验目的:通过实践,掌握常见的数据结构排序算法的原理与实现方法,比较不同算法的时间复杂度与空间复杂度,并分析其优缺点。

实验环境:编程语言:Python运行平台:Windows 10实验内容:1. 插入排序 (Insertion Sort)2. 冒泡排序 (Bubble Sort)3. 快速排序 (Quick Sort)4. 选择排序 (Selection Sort)5. 归并排序 (Merge Sort)6. 堆排序 (Heap Sort)实验步骤:1. 实现各种排序算法的函数,并验证其正确性。

2. 构建不同规模的随机数数组作为输入数据。

3. 使用time库测量每种算法在不同规模数据下的运行时间。

4. 绘制时间复杂度与输入规模的关系图。

5. 对比分析各种算法的时间复杂度和空间复杂度。

实验结果:1. 插入排序的时间复杂度为O(n^2),空间复杂度为O(1)。

2. 冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1)。

3. 快速排序的时间复杂度为O(nlogn),空间复杂度为O(logn)。

4. 选择排序的时间复杂度为O(n^2),空间复杂度为O(1)。

5. 归并排序的时间复杂度为O(nlogn),空间复杂度为O(n)。

6. 堆排序的时间复杂度为O(nlogn),空间复杂度为O(1)。

实验结论:1. 在小规模数据排序时,插入排序和冒泡排序由于其简单性和稳定性可以采用。

2. 在大规模数据排序时,快速排序、归并排序和堆排序由于其较低的时间复杂度可以采用。

3. 选择排序由于其时间复杂度较高,不适合用于大规模数据排序。

4. 归并排序由于其需要额外的空间存储中间结果,空间复杂度较高。

5. 快速排序由于其递归调用栈的使用,时间复杂度虽然较低,但空间复杂度较高。

综上所述,选择排序、插入排序和冒泡排序适用于小规模数据排序,而归并排序、快速排序和堆排序适用于大规模数据排序。

数据结构实验报告——排序

数据结构实验报告——排序

数据结构实验报告排序姓名:13-计算机-舞学号:0000000000专业:计算机科学与技术班级:计算机13-2班日期:2014年6月6日星期五一、实验目的和要求通过编程实现直接插入排序、希尔排序、冒泡排序、快速排序、直接选择排序。

要求输入一些无序数,执行程序后使他们变成有序数并在窗口输出。

二、实验环境1、windows 72、c-free 5.0三、实验内容用五种排序算法对输入的数进行排序,并在屏幕中输出。

四、实验过程1、直接插入排序:即将所需要排序的数据分成两部分,其中一部分为已排好序部分,另一部分为未排序部分。

然后从未排序部分中选出一元素插入到一排序部分中,要求插入后已排序部分任然有序。

在编写该程序时,我将要排序的数据储存在一个数组中,并将第一个数划分为已经排序部分然后从下一个数开始不断和前边的最后一个数比较,知道找到插入位置。

2、希尔排序:希尔排序是建立在直接插入排序的基础之上的,他是通过将数据分成几组,在组内实现插入排序,使整个数据基本有序,最后再对整个数据实现插入排序。

这里同样将数据储存在数组中,分组的步长每次取之前步长的一半。

需要注意的是,移动元素时,下标不再是减1,而是减去步长。

3、冒泡排序:通过不断比较相邻的两个元素,发现倒序即交换,最终实现排序。

在这个程序中,我从后面开始向前比较。

每依次循环可以最终确定一个元素在其最终位置上,所以每次循环之后,元素间的两两比较次数减1.4、快速排序:选定一个元素作为中间元素,将整个数据分为比中间元素小的一组和比中间元素大的一组,并且小的在中间元素前,大的在中间元素后。

再分好的两组内再次重复上诉过程使所有元素排好序。

5、直接选择排序:将待排序数据存入数组中,扫描一遍数组,将其中最小的元素找出并放在第一位,再扫描一遍剩下的元素,找到最小的放在第二位。

如此不断重复知道扫描了n-1次。

由于不要再开新空间,所以找到最小元素时用交换的方式使其放在第一位。

比如第一遍扫描,假设第一个为最小元素,再扫描过程中,如果发现比它小的数,则把第一个元素和该位置的元素交换。

《数据结构》实验报告——排序

《数据结构》实验报告——排序

《数据结构》实验报告排序实验题目:输入十个数,从插入排序,快速排序,选择排序三类算法中各选一种编程实现。

实验所使用的数据结构内容及编程思路:1.插入排序:直接插入排序的基本操作是,将一个记录到已排好序的有序表中,从而得到一个新的,记录增一得有序表。

一般情况下,第i趟直接插入排序的操作为:在含有i-1个记录的有序子序列r[1..i-1]中插入一个记录r[i]后,变成含有i个记录的有序子序列r[1..i];并且,和顺序查找类似,为了在查找插入位置的过程中避免数组下标出界,在r[0]处设置哨兵。

在自i-1起往前搜索的过程中,可以同时后移记录。

整个排序过程为进行n-1趟插入,即:先将序列中的第一个记录看成是一个有序的子序列,然后从第2个记录起逐个进行插入,直至整个序列变成按关键字非递减有序序列为止。

2.快速排序:基本思想是,通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

假设待排序的序列为{L.r[s],L.r[s+1],…L.r[t]},首先任意选取一个记录(通常可选第一个记录L.r[s])作为枢轴(或支点)(pivot),然后按下述原则重新排列其余记录:将所有关键字较它小的记录都安置在它的位置之前,将所有关键字较大的记录都安置在它的位置之后。

由此可以该“枢轴”记录最后所罗的位置i作为界线,将序列{L.r[s],…,L.r[t]}分割成两个子序列{L.r[i+1],L.[i+2],…,L.r[t]}。

这个过程称为一趟快速排序,或一次划分。

一趟快速排序的具体做法是:附设两个指针low和high,他们的初值分别为low和high,设枢轴记录的关键字为pivotkey,则首先从high所指位置起向前搜索找到第一个关键字小于pivotkey的记录和枢轴记录互相交换,然后从low所指位置起向后搜索,找到第一个关键字大于pivotkey的记录和枢轴记录互相交换,重复这两不直至low=high为止。

北邮数据结构实验报告-排序

北邮数据结构实验报告-排序

北邮数据结构实验报告-排序北邮数据结构实验报告-排序一、实验目的本实验旨在掌握常见的排序算法,包括冒泡排序、插入排序、选择排序、快速排序、归并排序等,并通过实际编程实现对数字序列的排序。

二、实验内容1.冒泡排序冒泡排序是一种简单的排序算法,其基本思想是依次比较相邻的两个元素,并按照从小到大或从大到小的顺序交换。

具体步骤如下:- 从待排序序列的第一个元素开始,依次比较相邻的两个元素;- 如果前面的元素大于后面的元素,则交换这两个元素的位置;- 重复上述步骤,直到整个序列有序。

2.插入排序插入排序是一种简单且直观的排序算法,其基本思想是将待排序序列分为已排序和未排序两部分,每次从未排序部分中选择一个元素插入到已排序部分的合适位置。

具体步骤如下:- 从待排序序列中选择一个元素作为已排序部分的第一个元素;- 依次将未排序部分的元素插入到已排序部分的合适位置,使得已排序部分保持有序;- 重复上述步骤,直到整个序列有序。

3.选择排序选择排序是一种简单且直观的排序算法,其基本思想是每次选择未排序部分中的最小(或最大)元素,并将其放在已排序部分的末尾。

具体步骤如下:- 在未排序部分中选择最小(或最大)的元素;- 将选择的最小(或最大)元素与未排序部分的第一个元素交换位置;- 重复上述步骤,直到整个序列有序。

4.快速排序快速排序是一种高效的排序算法,其基本思想是通过一趟排序将待排序序列分割成两部分,其中一部分的元素都比另一部分的元素小。

具体步骤如下:- 选择一个枢轴元素(一般选择第一个元素);- 将待排序序列中小于枢轴元素的元素放在枢轴元素的左侧,大于枢轴元素的元素放在枢轴元素的右侧;- 对枢轴元素左右两侧的子序列分别进行递归快速排序;- 重复上述步骤,直到整个序列有序。

5.归并排序归并排序是一种高效的排序算法,其基本思想是将待排序序列划分成足够小的子序列,然后对这些子序列进行两两合并,最终形成有序的序列。

具体步骤如下:- 将待排序序列递归地划分成足够小的子序列;- 对每个子序列进行归并排序;- 合并相邻的子序列,直到整个序列有序。

数据结构排序算法实验报告

数据结构排序算法实验报告
t=i; } e=list[t]; countsm++; list[t]=list[j]; countsm++; list[j]=e; countsm++; } cout<<"选择排序比较次数:"<<countsc<<" "<<"选择排序移动次数:"<<countsm<<endl; } //快速排序 void QSort(Element *list,int m,int n) { int i,j,k,temp; if(m<n) { i=m; j=n+1; k=list[m].GetKey(); while(i<j) {
移动次数 735219 247071 2997 7296 22836 4233
乱序 2 比较次数 496238 255211 499500 12927 14868 3788
移动次数 762636 256210 2997 7449 22 242989 499500 12951 14845 3818
希尔排序:void ShellSort(Element *list,int n) 记录移动和比较次数的变量:int countlm=0,countlc=0 希尔排序是将文件分组,然后进行插入排序,因此 countlm,countlc 的增量方式与直 接插入排序相同。
堆排序:void HeapSort(Element *list,const int n) 记录移动和比较次数的变量:int countrm=0,countrc=0 首先进行初始建堆 void Restore(Element *tree,const int root,const int n),将待排序文 件保存在完全二叉树中,从最后一个非叶节点开始,将其孩子结点与其进行比较, 每比较一次 countrc 加 1,若孩子结点比其大,二者交换 countrm 加 3,直到任意结 点的关键词大于等于它的两个孩子结点。在进行堆排序,将根节点与最后一个叶节 点交换,countrm 加 3,再进行初始建堆,直至完全排好序。

数据结构实验报告排序

数据结构实验报告排序

数据结构实验报告排序数据结构实验报告:排序引言:排序是计算机科学中常见的算法问题之一,它的目标是将一组无序的数据按照特定的规则进行排列,以便于后续的查找、统计和分析。

在本次实验中,我们将学习和实现几种常见的排序算法,并对它们的性能进行比较和分析。

一、冒泡排序冒泡排序是最简单的排序算法之一,它通过不断交换相邻的元素,将较大(或较小)的元素逐渐“冒泡”到数组的一端。

具体实现时,我们可以使用两层循环来比较和交换元素,直到整个数组有序。

二、插入排序插入排序的思想是将数组分为两个部分:已排序部分和未排序部分。

每次从未排序部分中取出一个元素,插入到已排序部分的适当位置,以保持已排序部分的有序性。

插入排序的实现可以使用一层循环和适当的元素交换。

三、选择排序选择排序每次从未排序部分中选择最小(或最大)的元素,与未排序部分的第一个元素进行交换。

通过不断选择最小(或最大)的元素,将其放置到已排序部分的末尾,从而逐渐形成有序序列。

四、快速排序快速排序是一种分治的排序算法,它通过选择一个基准元素,将数组划分为两个子数组,其中一个子数组的所有元素都小于等于基准元素,另一个子数组的所有元素都大于基准元素。

然后对两个子数组分别递归地进行快速排序,最终将整个数组排序。

五、归并排序归并排序也是一种分治的排序算法,它将数组划分为多个子数组,对每个子数组进行排序,然后再将排好序的子数组合并成一个有序的数组。

归并排序的实现可以使用递归或迭代的方式。

六、性能比较与分析在本次实验中,我们对以上几种排序算法进行了实现,并通过对不同规模的随机数组进行排序,比较了它们的性能。

我们使用了计算排序时间的方式,并记录了每种算法在不同规模下的运行时间。

通过对比实验结果,我们可以得出以下结论:1. 冒泡排序和插入排序在处理小规模数据时表现较好,但在处理大规模数据时性能较差,因为它们的时间复杂度为O(n^2)。

2. 选择排序的时间复杂度也为O(n^2),与冒泡排序和插入排序相似,但相对而言,选择排序的性能稍好一些。

(完整word版)数据结构各种排序实验报告

(完整word版)数据结构各种排序实验报告

目录1。

引言 .................................................................................................................... 错误!未定义书签。

2.需求分析 (2)3.详细设计 (2)3。

1 直接插入排序 (2)3.2折半排序 (2)3。

3 希尔排序 (4)3。

4简单选择排序 (4)3.5堆排序 (4)3。

6归并排序 (5)3。

7冒泡排序 (7)4.调试 (8)5.调试及检验 (8)5.1 直接插入排序 (8)5。

2折半插入排序 (9)5。

3 希尔排序 (10)5。

4简单选择排序 (10)5。

5堆排序 (11)5.6归并排序 (12)5。

7冒泡排序 (12)6。

测试与比较........................................................................................................ 错误!未定义书签。

6.1调试步骤.................................................................................................... 错误!未定义书签。

6.2结论 (13)7.实验心得与分析 (13)8.附录 (14)8。

1直接插入排序 (14)8.2折半插入排序 (15)8。

3希尔排序 (17)8。

4简单选择排序 (18)8。

5堆排序 (20)8。

6归并排序 (22)8.7冒泡排序 (25)8.8主程序 (26)1。

需求分析课程题目是排序算法的实现,课程设计一共要设计八种排序算法。

这八种算法共包括:堆排序,归并排序,希尔排序,冒泡排序,快速排序,基数排序,折半插入排序,直接插入排序。

为了运行时的方便,将八种排序方法进行编号,其中1为堆排序,2为归并排序,3为希尔排序,4为冒泡排序,5为快速排序,6为基数排序,7为折半插入排序8为直接插入排序。

排序实验报告的结果总结(3篇)

排序实验报告的结果总结(3篇)

第1篇一、实验背景随着计算机科学和信息技术的发展,排序算法在数据处理的领域中扮演着至关重要的角色。

本实验旨在通过对比几种常见的排序算法,分析它们的性能差异,为实际应用中选择合适的排序算法提供参考。

二、实验目的1. 熟悉几种常见排序算法的基本原理和实现方法。

2. 分析不同排序算法的时间复杂度和空间复杂度。

3. 比较不同排序算法在不同数据规模下的性能差异。

4. 为实际应用提供选择排序算法的依据。

三、实验方法1. 选择实验数据:随机生成一组包含10000个整数的数组,分别用于测试不同排序算法的性能。

2. 实现排序算法:分别实现冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序等常见排序算法。

3. 性能测试:分别对每组实验数据进行排序,记录每种排序算法的运行时间。

4. 数据分析:对比不同排序算法的时间复杂度和空间复杂度,分析其性能差异。

四、实验结果1. 冒泡排序冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1)。

在测试数据规模为10000时,冒泡排序的运行时间为234.5秒。

2. 选择排序选择排序的时间复杂度为O(n^2),空间复杂度为O(1)。

在测试数据规模为10000时,选择排序的运行时间为237.1秒。

3. 插入排序插入排序的时间复杂度为O(n^2),空间复杂度为O(1)。

在测试数据规模为10000时,插入排序的运行时间为239.8秒。

4. 快速排序快速排序的平均时间复杂度为O(nlogn),空间复杂度为O(logn)。

在测试数据规模为10000时,快速排序的运行时间为18.5秒。

5. 归并排序归并排序的时间复杂度为O(nlogn),空间复杂度为O(n)。

在测试数据规模为10000时,归并排序的运行时间为20.3秒。

6. 堆排序堆排序的时间复杂度为O(nlogn),空间复杂度为O(1)。

在测试数据规模为10000时,堆排序的运行时间为19.7秒。

五、结果分析1. 时间复杂度方面:快速排序、归并排序和堆排序的平均时间复杂度均为O(nlogn),优于冒泡排序、选择排序和插入排序的O(n^2)时间复杂度。

各排序算法实验报告(3篇)

各排序算法实验报告(3篇)

第1篇一、实验目的本次实验旨在通过编程实现几种常见的排序算法,并对其进行性能分析,以加深对排序算法原理的理解,掌握不同排序算法的适用场景,提高算法设计能力。

二、实验内容本次实验选择了以下几种排序算法:冒泡排序、插入排序、快速排序、归并排序、希尔排序、选择排序和堆排序。

以下是对每种算法的简要介绍和实现:1. 冒泡排序(Bubble Sort)冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。

遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。

```cvoid bubbleSort(int arr[], int n) {int i, j, temp;for (i = 0; i < n - 1; i++) {for (j = 0; j < n - i - 1; j++) {if (arr[j] > arr[j + 1]) {temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}}```2. 插入排序(Insertion Sort)插入排序是一种简单直观的排序算法。

它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

```cvoid insertionSort(int arr[], int n) {int i, key, j;for (i = 1; i < n; i++) {key = arr[i];j = i - 1;while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j = j - 1;}arr[j + 1] = key;}}```3. 快速排序(Quick Sort)快速排序是一种分而治之的排序算法。

它将原始数组分成两个子数组,一个包含比基准值小的元素,另一个包含比基准值大的元素,然后递归地对这两个子数组进行快速排序。

数据结构实验报告——排序

数据结构实验报告——排序

2008级数据结构实验报告实验名称:实验四排序学生姓名:班级:班内序号:学号:日期:2009年12月6日1.实验要求a. 实验目的通过实现下述实验内容,学习、实现、对比各种排序算法,掌握各种排序算法的优劣,以及各种算法使用的情况。

b. 实验内容使用简单数组实现下面各种排序算法,并进行比较。

排序算法:1、插入排序2、希尔排序3、冒泡排序4、快速排序5、简单选择排序6、堆排序(选作)7、归并排序(选作)8、基数排序(选作)9、其他2. 程序分析2.1 存储结构存储结构:顺序存储结构示意图如下:2.2 关键算法分析核心算法思想:1.利用教材讲述的基本算法思想,实现七种排序算法,统计其运行相关数据。

2.将七种排序函数入口地址作为函数指针数组,实现快速调用和统计。

使得程序代码可读性增、结构更加优化。

关键算法思想描述和实现:关键算法1:实现七种算法的基本排序功能。

1、插入排序:依次将待排序的序列中的每一个记录插入到先前排序好的序列中,直到全部记录排序完毕。

2、希尔排序:先将整个序列分割成若干个子列,分别在各个子列中运用直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序。

3、冒泡排序:两两比较相邻记录的关键码,如果反序则交换,直到没有反序记录为止。

4、快速排序:首先选择一个基准,将记录分割为两部分,左支小于或等于基准,右支则大于基准,然后对两部分重复上述过程,直至整个序列排序完成。

5、选择排序:从待排序的记录序列中选择关键码最小(或最大)的记录并将它与序列中的第一个记录交换位置;然后从不包括第一个位置上的记录序列中选择关键码最小(或最大)的记录并将它与序列中的第二个记录交换位置;如此重复,直到序列中只剩下一个记录为止。

6、堆排序:通过建立大根堆或者小根堆,取出根节点,反复调整堆使之保持大根堆或者小根堆,直至最后序列有序。

7、归并排序:将若干个有序序列两两归并,直至所有待排序的记录都在一个有序序列为止。

数据结构排序实验报告

数据结构排序实验报告

引言概述:数据结构排序实验是计算机科学与技术专业中一项重要的实践课程。

通过实验,可以深入理解和掌握不同排序算法的原理、特点和性能表现。

本文将针对数据结构排序实验进行详细的阐述和总结,包括实验目的、实验内容、实验结果分析和总结。

一、实验目的1. 加深对数据结构排序算法的理解:通过实验,掌握不同排序算法的工作原理和实现方式。

2. 分析和比较不同排序算法的性能:对比不同排序算法在不同数据规模下的时间复杂度和空间复杂度,理解它们的优劣势。

3. 提高编程和算法设计能力:通过实验的编写,提升对排序算法的实现能力和代码质量。

二、实验内容1. 选择排序算法:选择排序是一种简单直观的排序算法,将序列分为有序和无序两部分,每次从无序部分选择最小(最大)元素,放到有序部分的末尾(开头)。

- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析2. 插入排序算法:插入排序逐步构建有序序列,对于未排序的元素,在已排序序列中从后向前扫描,找到对应位置插入。

- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析3. 快速排序算法:快速排序利用分治的思想,将序列分为左右两部分,选取基准元素,将小于基准的放在左边,大于基准的放在右边,递归地对左右部分进行排序。

- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析4. 归并排序算法:归并排序是一种稳定的排序算法,通过将序列分为若干子序列,分别进行排序,然后再将排好序的子序列合并成整体有序序列。

- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析5. 堆排序算法:堆是一种特殊的树状数据结构,堆排序利用堆的性质进行排序,通过构建大顶堆或小顶堆,并逐个将堆顶元素移出形成有序序列。

- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析三、实验结果分析1. 比较不同排序算法的执行时间:根据实验数据和分析,对比不同排序算法在不同数据规模下的执行时间,并针对其时间复杂度进行验证和分析。

数据排序法实验报告

数据排序法实验报告

一、实验目的1. 理解并掌握常见的几种数据排序算法。

2. 分析不同排序算法的优缺点和适用场景。

3. 通过实际操作,提高编程能力和数据结构处理能力。

二、实验内容1. 实验环境:Windows 10操作系统,Python 3.7编程语言。

2. 实验数据:一组随机生成的整数序列。

3. 实验步骤:(1)编写代码实现冒泡排序、选择排序、插入排序、快速排序、归并排序等算法;(2)对比分析不同排序算法的执行时间和稳定性;(3)根据实际需求,选择合适的排序算法。

三、实验结果与分析1. 冒泡排序冒泡排序的基本思想是通过相邻元素的比较和交换,逐步将待排序序列中的元素按从小到大的顺序排列。

```pythondef bubble_sort(arr):n = len(arr)for i in range(n):for j in range(0, n-i-1):if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]return arr```冒泡排序的复杂度为O(n^2),适用于小规模数据排序。

2. 选择排序选择排序的基本思想是每次从待排序序列中选出最小(或最大)元素,然后放到序列的起始位置。

```pythondef selection_sort(arr):n = len(arr)for i in range(n):min_idx = ifor j in range(i+1, n):if arr[min_idx] > arr[j]:min_idx = jarr[i], arr[min_idx] = arr[min_idx], arr[i]return arr```选择排序的复杂度也为O(n^2),适用于小规模数据排序。

3. 插入排序插入排序的基本思想是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增加1的有序表。

```pythondef insertion_sort(arr):for i in range(1, len(arr)):key = arr[i]j = i-1while j >=0 and key < arr[j]:arr[j+1] = arr[j]j -= 1arr[j+1] = keyreturn arr```插入排序的复杂度为O(n^2),适用于小规模数据排序。

数据结构课程设计实验报告(各种排序的实现与效率分析)

数据结构课程设计实验报告(各种排序的实现与效率分析)

数据结构课程设计实验报告1、需求分析(1)对起泡排序、直接排序、简单选择排序、快速排序、希尔排序、堆排序算法进行比较;(2)待排序表的表长不小于100,表中数据随机产生,至少用5组不同数据作比较,比较指标有:关键字参加比较次数和关键字的移动次数(关键字进行一次交换操作记为3次移动);(3)输出比较结果。

2、主要函数及数据类型typedef int KeyType; //定义关键字类型为整数类型typedef int InfoType; //定义关键字类型为整数类型typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等*/typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */typedef struct{KeyType key; //关键字项InfoType otherinfo; //其它数据项}RedType; //记录类型typedef struct {RedType r[MAXSIZE+1]; //r[0]闲置或用作哨兵单元int length; //顺序表长度}SqList; //顺序表类型3、源代码/*头文件和宏定义部分*/#include"string.h"#include"ctype.h"#include"time.h"#include"malloc.h" /* malloc()等*/#include"limits.h" /* INT_MAX等*/#include"stdio.h" /* EOF(=^Z或F6),NULL */#include"stdlib.h" /* atoi() */#include"io.h" /* eof() */#include"math.h" /* floor(),ceil(),abs() */#include"process.h" /* exit() *//* 函数结果状态代码*/#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define MAXSIZE 100 //示例数据类型的最大长度typedef int KeyType; //定义关键字类型为整数类型typedef int InfoType; //定义关键字类型为整数类型typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等*/ typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */typedef struct{KeyType key; //关键字项InfoType otherinfo; //其它数据项}RedType; //记录类型typedef struct {RedType r[MAXSIZE+1]; //r[0]闲置或用作哨兵单元int length; //顺序表长度}SqList; //顺序表类型void InitData(SqList *L,int dataCopy[]){int i;L->length=MAXSIZE;srand((unsigned)time(NULL));for(i=0;i<=MAXSIZE;i++){L->r[i].otherinfo=0;dataCopy[i]=L->r[i].key=rand();}}void PrintData(SqList L){int i;for(i=1;i<=L.length;i++){printf("%d\t",L.r[i].key);}}void ResumeData(SqList *L,int dataCopy[]){int i;for(i=0;i<=MAXSIZE;i++){L->r[i].key=dataCopy[i];}}void PrintStatistic(int *compareCounts,int *moveCounts){printf("\n\t\t各种排序方法比较结果:\n\n");printf("\t\t起泡排序: 比较次数%d,移动次数%d\n",compareCounts[0],moveCounts[0]);printf("\t\t直接插入排序:比较次数%d,移动次数%d\n",compareCounts[1],moveCounts[1]);printf("\t\t简单选择排序:比较次数%d,移动次数%d\n",compareCounts[2],moveCounts[2]);printf("\t\t快速排序: 比较次数%d,移动次数%d\n",compareCounts[3],moveCounts[3]);printf("\t\t希尔排序: 比较次数%d,移动次数%d\n",compareCounts[4],moveCounts[4]);printf("\t\t堆排序: 比较次数%d,移动次数%d\n",compareCounts[5],moveCounts[5]);}/*******************************直接插入排序*******************************/void InsertSort(SqList *L,int *compareCounts,int *moveCounts ) //直接插入排序{int i,j; //for(i=2;i<=L->length;i++) //从顺序表的第二个元素开始进行比较{if(L->r[i].key<L->r[i-1].key) //将每个元素与它的前一个元素关键字进行比较{L->r[0]=L->r[i]; //如果关键字比前一个元素关键字小,就将元素复制作为哨兵L->r[i]=L->r[i-1];(*moveCounts)+=2; //关键字移动了2次j=i-2; //从要比较的关键字的前第二个记录开始进行比较,然后后移while(L->r[0].key<L->r[j].key){L->r[j+1]=L->r[j]; //记录后移(*moveCounts)++; //每作一次后移,移动次数加1j--;(*compareCounts)++; //每作一次比较,比较次数加1}L->r[j+1]=L->r[0]; //插入到正确位置}(*compareCounts)++;}}/*******************************希尔排序*******************************/void ShellInsert(SqList *L,int increment,int *compareCounts,int *moveCounts){ //对顺序表作一趟希尔插入排序int j,n;for(j=1+increment;j<=L->length;j++){if(L->r[j].key<L->r[j-increment].key) //将L->[i]插入到有序增量子表{L->r[0]=L->r[j]; //暂存在L->r[0]L->r[j]=L->r[j-increment];(*moveCounts)+=2;for(n=j-2*increment;n>0&&L->r[0].key<L->r[n].key;n-=increment){L->r[n+increment]=L->r[n]; //记录后移,查找插入位置(*moveCounts)++;(*compareCounts)++;}L->r[n+increment]=L->r[0]; //插入(*moveCounts)++;}(*compareCounts)++;}}void ShellSort(SqList *L,int IncreList[],int times,int *compareCounts,int *moveCounts) //希尔排序{ //按增量序列Increlist[0.....times-1]对顺序表L作希尔排序int k; //for(k=0;k<times;k++){ShellInsert(L,IncreList[k],compareCounts,moveCounts); //一趟增量为IncreList[k]的插入排序}}/*******************************起泡排序*******************************/void BubbleSort(SqList *L,int *compareCounts,int *moveCounts) //起泡排序{int i,j;for(i=1;i<=L->length;i++){for(j=L->length;j>i;j--){ //从后往前两两进行比较,将元素关键字小的交换到前面if(L->r[j].key<L->r[j-1].key){L->r[0]=L->r[j];L->r[j]=L->r[j-1];L->r[j-1]=L->r[0];(*moveCounts)+=3;}(*compareCounts)++;}}}/*******************************快速排序*******************************/int Partition(SqList *L,int low,int high,int *compareCounts,int *moveCounts) //快速排序中的分{int pivotkey;L->r[0]=L->r[low];(*moveCounts)++;pivotkey=L->r[low].key;while(low<high){while(low<high&&L->r[high].key>=pivotkey){high--;(*compareCounts)++;}L->r[low]=L->r[high];(*moveCounts)++;while(low<high&&L->r[low].key<=pivotkey){low++;(*compareCounts)++;}L->r[high]=L->r[low];(*moveCounts)++;(*compareCounts)++;}L->r[low]=L->r[0];(*moveCounts)++;return low;}void QSort(SqList *L,int low,int high,int *compareCounts,int *moveCounts){int pivotloc;if(low<high){pivotloc=Partition(L,low,high,compareCounts,moveCounts);QSort(L,low,pivotloc-1,compareCounts,moveCounts);QSort(L,pivotloc+1,high,compareCounts,moveCounts);}}void QuickSort(SqList *L,int *compareCounts,int *moveCounts){QSort(L,1,L->length,compareCounts,moveCounts);}/*******************************简单选择排序*******************************/void SelectSort(SqList *L,int *compareCounts,int *moveCounts){int i,j,minPoint;for(i=1;i<=L->length;i++){L->r[0]=L->r[i];(*moveCounts)++;minPoint=i;for(j=i+1;j<=L->length;j++){if(L->r[j].key<L->r[0].key){L->r[0]=L->r[j];(*moveCounts)++;minPoint=j;}(*compareCounts)++;}L->r[minPoint]=L->r[i];L->r[i]=L->r[0];(*moveCounts)++;}}/*******************************堆排序*******************************/void HeapAdjust(SqList *L,int s,int m,int *compareCounts,int *moveCounts){RedType cmpKey; //待比较的值int j;cmpKey=L->r[s];(*moveCounts)++;for(j=s*2;j<=m;j*=2){(*compareCounts)+=2;if(j<m&&L->r[j].key<L->r[j+1].key) j++;if(!(cmpKey.key<L->r[j].key)) break;L->r[s]=L->r[j];(*moveCounts)++;s=j;}L->r[s]=cmpKey;(*moveCounts)++;}void HeapSort(SqList *L,int *compareCounts,int *moveCounts){int i;RedType temp;for(i=L->length/2;i>0;i--) HeapAdjust(L,i,L->length,compareCounts,moveCounts);for(i=L->length;i>1;i--){temp=L->r[1];L->r[1]=L->r[i];L->r[i]=temp;(*moveCounts)+=3;HeapAdjust(L,1,i-1,compareCounts,moveCounts);}}void SortCompare(){SqList L; //用顺序表存放待排序的元素int dataCopy[MAXSIZE+1],i;int compareCounts[7],moveCounts[7];int increList[6];for(i=0;i<5;i++){increList[i]=(int)pow(2,7-i)-1;}increList[5]=1;for(i=0;i<7;i++){compareCounts[i]=0;moveCounts[i]=0;}InitData(&L,dataCopy); //初始化数据,随机产生100个正整数的数列printf("\t\t\t初始化数据后产生的数列:\n");PrintData(L); //显示出未排序的数列printf("\n\n\t\t\t经过起泡排序后产生的数列:\n");BubbleSort(&L,&compareCounts[0],&moveCounts[0]); //对数列使用起泡排序PrintData(L); //显示出排序好的数列ResumeData(&L,dataCopy);printf("\n\n\t\t\t经过直接插入排序后产生的数列:\n");InsertSort(&L,&compareCounts[1],&moveCounts[1]); //对数列使用插入排序PrintData(L); //显示出排序好的数列ResumeData(&L,dataCopy);printf("\n\n\t\t\t经过简单选择排序后产生的数列:\n");SelectSort(&L,&compareCounts[2],&moveCounts[2]); //对数列使用简单选择排序PrintData(L); //显示出排序好的数列ResumeData(&L,dataCopy);printf("\n\n\t\t\t经过快速排序后产生的数列:\n");QuickSort(&L,&compareCounts[3],&moveCounts[3]); //对数列使用快速排序PrintData(L); //显示出排序好的数列ResumeData(&L,dataCopy);printf("\n\n\t\t\t经过希尔排序后产生的数列:\n");ShellSort(&L,increList,6,&compareCounts[4],&moveCounts[4]); //对数列使用希尔排序PrintData(L); //显示出排序好的数列ResumeData(&L,dataCopy);printf("\n\n\t\t\t经过堆排序后产生的数列:\n");HeapSort(&L,&compareCounts[5],&moveCounts[5]); //对数列使用堆排序PrintData(L); //显示出排序好的数列PrintStatistic(compareCounts,moveCounts);}main(){int i,temp;for(i=0;i<5;i++){SortCompare();printf("\n\t\t请按任意键进行下一组数据的排序对比\n\n");temp=getchar();}}4、调试分析成功运行,如图所示:。

数据结构课程设计排序实验报告

数据结构课程设计排序实验报告

《数据结构》课程设计报告专业班级姓名学号指导教师起止时间课程设计:排序综合一、任务描述利用随机函数产生n个随机整数(20000以上),对这些数进行多种方法进行排序。

(1)至少采用三种方法实现上述问题求解(提示,可采用的方法有插入排序、希尔排序、起泡排序、快速排序、选择排序、堆排序、归并排序)。

并把排序后的结果保存在不同的文件中。

(2)统计每一种排序方法的性能(以上机运行程序所花费的时间为准进行对比),找出其中两种较快的方法。

要求:根据以上任务说明,设计程序完成功能。

二、问题分析1、功能分析分析设计课题的要求,要求编程实现以下功能:(1)随机生成N个整数,存放到线性表中;(2)起泡排序并计算所需时间;(3)简单选择排序并计算时间;(4)希尔排序并计算时间;(5)直接插入排序并计算所需时间;(6)时间效率比较。

2、数据对象分析存储数据的线性表应为顺序存储。

三、数据结构设计使用顺序表实现,有关定义如下:typedef int Status;typedef int KeyType ; //设排序码为整型量typedef int InfoType;typedef struct { //定义被排序记录结构类型KeyType key ; //排序码I nfoType otherinfo; //其它数据项} RedType ;typedef struct {RedType * r; //存储带排序记录的顺序表//r[0]作哨兵或缓冲区int length ; //顺序表的长度} SqList ; //定义顺序表类型四、功能设计(一)主控菜单设计为实现通各种排序的功能,首先设计一个含有多个菜单项的主控菜单程序,然后再为这些菜单项配上相应的功能。

程序运行后,给出5个菜单项的内容和输入提示,如下:1.起泡排序2.简单选择排序3.希尔排序4. 直接插入排序0. 退出系统(二)程序模块结构由课题要求可将程序划分为以下几个模块(即实现程序功能所需的函数):●主控菜单项选择函数menu()●创建排序表函数InitList_Sq()●起泡排序函数Bubble_sort()●简单选择排序函数SelectSort()●希尔排序函数ShellSort();●对顺序表L进行直接插入排序函数Insertsort()(三)函数调用关系程序的主要结构(函数调用关系)如下图所示。

数据结构排序实验报告

数据结构排序实验报告

数据结构排序实验报告一、实验目的本次数据结构排序实验的主要目的是深入理解和掌握常见的排序算法,包括冒泡排序、插入排序、选择排序、快速排序和归并排序,并通过实际编程和实验分析,比较它们在不同规模数据下的性能表现,从而为实际应用中选择合适的排序算法提供依据。

二、实验环境本次实验使用的编程语言为 Python 3x,开发环境为 PyCharm。

实验中使用的操作系统为 Windows 10。

三、实验原理1、冒泡排序(Bubble Sort)冒泡排序是一种简单的排序算法。

它重复地走访要排序的数列,一次比较两个数据元素,如果顺序不对则进行交换,并一直重复这样的走访操作,直到没有要交换的数据元素为止。

2、插入排序(Insertion Sort)插入排序是一种简单直观的排序算法。

它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入,直到整个数组有序。

3、选择排序(Selection Sort)首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

以此类推,直到所有元素均排序完毕。

4、快速排序(Quick Sort)通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

5、归并排序(Merge Sort)归并排序是建立在归并操作上的一种有效、稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。

四、实验步骤1、算法实现使用 Python 语言分别实现上述五种排序算法。

为每个算法编写独立的函数,函数输入为待排序的列表,输出为排序后的列表。

2、生成测试数据生成不同规模(例如 100、500、1000、5000、10000 个元素)的随机整数列表作为测试数据。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

目录1.引言............................................................................................................................ 错误!未定义书签。

2.需求分析 (2)3.详细设计 (2)3.1 直接插入排序 (2)3.2折半排序 (2)3.3 希尔排序 (4)3.4简单选择排序 (4)3.5堆排序 (4)3.6归并排序 (5)3.7冒泡排序 (7)4.调试 (8)5.调试及检验 (9)5.1 直接插入排序 (9)5.2折半插入排序 (9)5.3 希尔排序 (10)5.4简单选择排序 (10)5.5堆排序 (11)5.6归并排序 (12)5.7冒泡排序 (12)6.测试与比较................................................................................................................ 错误!未定义书签。

6.1调试步骤......................................................................................................... 错误!未定义书签。

6.2结论 (13)7.实验心得与分析 (13)8.附录 (15)8.1直接插入排序 (15)8.2折半插入排序 (16)8.3希尔排序 (18)8.4简单选择排序 (20)8.5堆排序 (21)8.6归并排序 (24)8.7冒泡排序 (27)8.8主程序 (28)1.需求分析课程题目是排序算法的实现,课程设计一共要设计八种排序算法。

这八种算法共包括:堆排序,归并排序,希尔排序,冒泡排序,快速排序,基数排序,折半插入排序,直接插入排序。

为了运行时的方便,将八种排序方法进行编号,其中1为堆排序,2为归并排序,3为希尔排序,4为冒泡排序,5为快速排序,6为基数排序,7为折半插入排序8为直接插入排序。

软件环境:Windows-7操作系统,所使用的软件为c-Free;2.概要设计2.1 直接插入排序⑴算法思想:直接插入排序是一种最简单的排序方法,它的基本操作是将一个记录插入到一个已排好序的有序表中,从而得到一个新的、记录数增一的有序表。

在自i-1起往前搜索的过程中,可以同时后移记录。

整个排序过程为进行n-1趟插入,即:先将序列中的第一个记录看成是一个有序的子序列,然后从第二个记录起逐个进行插入,直至整个序列变成按关键字非递减有序序列为止。

⑵程序实现及核心代码的注释:for (i = 1 ; i < r.length ;++i )for(j=0;j < i;++j)if(r.base[i] < r.base[j]){temp = r.base[i]; //保存待插入记录for(i= i ;i > j; --i )r.base[i] = r.base[i-1]; //记录后移r.base[j] = temp; //插入到正确的为位置}r.base[r.length] ='\0';2.2折半排序⑴算法思想:由于折半插入排序的基本操作是在一个有序表中进行查找和插入,这个“查找”操作可利用折半查找来实现,由此进行的插入排序称之为折半插入排序。

折半插入排序所需附加存储空间和直接插入排序相同,从时间上比较,这般插入排序仅减少了关键字间的比较次数,而记录的移动次数不变。

因此,这般插入排序的时间复杂度仍为O(n2)。

⑵程序实现及核心代码的注释:void zb(FILE *fp){ //对顺序表作折半插入排序for ( i = 1 ; i < r.length ; i++ ){temp=r.base[i]; //将r.base[i]寄存在temp中low=0;high=i-1;while( low <= high ) //在base[low]到key[high]中折半查找有序插入的位置{m = (low+high)/2; //折半if ( temp < r.base[m] )high = m-1; //插入低半区elselow = m+1; //插入高半区}for( j=i-1; j>=high+1; --j )r.base[j+1]= r.base[j]; //记录后移r.base[high+1]=temp; //插入}2.3 希尔排序⑴算法思想:先将整个待排记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。

其中,子序列的构成不是简单的“逐段分割”,而是将分隔某个“增量”的记录组成一个子序列。

⑵程序实现及核心代码的注释:for(k = 0; k < 10 ; k++){m = 10 - k;for( i = m ; i < r.length; i ++ )if(r.base[i] < r.base[i - m]){temp = r.base[i]; //保存待插记录for(j = i - m ; j >= 0 && temp < r.base[j]; j -= m)r.base[ j + m ] = r.base[j]; //记录后移,查找插入位置r.base[ j + m ] = temp; //插入}}2.4简单选择排序⑴算法思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。

⑵程序实现及核心代码的注释:for ( i = 0 ; i < r.length ; i++ ){ //i为排好序的数的下标,依次往后存放排//好序的数temp=r.base[i]; //将待放入排好序的数的下标的数保存for( j = i,m = j +1 ; m < r.length ; m++) //找出未排序的数中最小的数的循环;if(r.base[j] > r.base[m])j = m;r.base[i] = r.base[j]; //把下标为j的数与i数互换;r.base[j] = temp;}2.5堆排序⑴算法思想:堆排序只需要一个记录大小的辅助空间,每个待排序的记录仅占有一个存储空间。

将序列所存储的元素A[N]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:树中任一非叶结点的元素均不大于(或不小于)其左右孩子(若存在)结点的元素。

算法的平均时间复杂度为O(N log N)。

⑵程序实现及核心代码的注释:void dp(FILE *fp){for(i = r.length / 2;i >= 1 ; --i) //把r.base[1...r.length]建成大顶堆HeapAdjust(r.base,i,r.length);for(i = r.length ;i >= 2 ; --i){temp = r.base[1];r.base[1] = r.base[i];r.base[i] = temp;HeapAdjust(r.base,1,i-1); //将r.base[1...i-1]重新调整为大顶堆}void HeapAdjust(char *r,int k,int m){i=k; x=r[i]; j=2*i; //沿key 较大的孩子节点向下筛选while(j<=m) //j为key较大的记录的下标{if( (j<m) && (r[j]>r[j+1]) )j++;if(x>r[j]){ //插入字符比当前的大,交换r[i] =r[j];i = j;j *= 2;}else //否则比较停止。

j = m + 1;}r[i] = x; //把字符x插入到该位置,元素插入实现}2.6归并排序⑴算法思想:先将相邻的个数为1的每两组数据进行排序合并;然后对上次归并所得到的大小为2的组进行相邻归并;如此反复,直到最后并成一组,即排好序的一组数据。

⑵程序实现及核心代码的注释:void merge(SqList6 r,int h ,int m ,int w ,SqList6 t){ //对相邻两组数据进行组合排序;int i,j,k;i = h ;j = m + 1; //j为合并的第二组元素的第一个数位置k =h-1;// k为存入t中的数的位置;while((i <= m)&&(j <= w)){ //依次排列两组数据k++;if(r.base[i] <= r.base[j]) //将第一组数据与第二组数据分别比较;t.base[k] = r.base[i++];elset.base[k] = r.base[j++];}if(i > m) //第一组数据先排完的情况while(j <= w) t.base[++k]=r.base[j++];elsewhile(i <= m) t.base[++k]=r.base[i++];}void tgb(int s,int n,SqList6 r,SqList6 t){ //对数据进行每组s个数的归并排序;int i=1; //i为要合并两组元素的第一个数位置;while(i<=(n-2*s+1)){merge(r,i,i+s-1,i+2*s-1,t); //i+s-1为要合并的第一组元素的最后一//数位置、i+2*s-1 为要合并的两组元素//最后一个数位置;i=i+2*s;}if(i<(n-s+1)) //考虑n不能被s整除,如果余下的数少于//2*s 但大于s,也就是余下的数不能凑成//两组,凑一组有余,则把余下的数进行组//合,并对其进行排序;merge(r,i,i+s-1,n,t);else //如果余下的数少于s,则余下的数进行组//合,并进行排序;while(i<=n)t.base[i]=r.base[i++];}void gb(FILE *fp) // 归并主函数;{n = r.length;SqList6 t;t.base=(char *) malloc(r.stacksize*sizeof(char));//给待排序的数组t申请内存;while(s<n) //每组元素不断增加循环进行合并排序;{tgb(s,n,r,t); // s为每组元素的个数、n为元素总个数、r//为原数组,t为待排序的数组,进行归并排s*=2; //序;把元素个数相同的两组合并并进行重新//定义成新的一组,此组元素个数为2*s;if(s<n){ tgb(s,n,t,r); s *= 2; }//当元素个数小于n时,对其进行合并排序;else //当元素个数大于n时,对剩下的数排序;{i=0;while(i<=n){r.base[i]=t.base[i+1];i++;}}}}2.7冒泡排序⑴算法思想:1、先将一组未排序的数组的最后一个数与倒数第二个数进行比较,并将较小的数放于两个数中较前的位置,然后将比较后的较小的数与倒数第三个进行比较,依次比较到第一个数,即可得到第一个数是所有数中最小的数;2、然后再将数组的最后一个数与倒数第二个数进行比较,并将较小的数放于两个数中较前的位置,依次比较到第二个数,3、如此循环到只剩最后两个比较,即得到排好序的一组数。

相关文档
最新文档