数据结构实验报告记录(四):实现典型的排序算法
排序的实验报告范文
![排序的实验报告范文](https://img.taocdn.com/s3/m/bba709f39f3143323968011ca300a6c30c22f18a.png)
排序的实验报告范文数据结构实验报告实验名称:实验四排序学生姓名:班级:班内序号:学号:日期: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)。
数据结构实验四报告排序
![数据结构实验四报告排序](https://img.taocdn.com/s3/m/493fe2a81711cc7931b716fe.png)
数据结构实验报告实验名称:实验四——排序学生姓名:班级:班内序号:学号:日期: 2013年12月16日1.实验要求使用简单数组实现下面各种排序算法,并进行比较。
排序算法:1、插入排序2、希尔排序3、冒泡排序4、快速排序5、简单选择排序6、堆排序(选作)7、归并排序(选作)8、基数排序(选作)9、其他要求:1、测试数据分成三类:正序、逆序、随机数据2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。
3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)4、对2和3的结果进行分析,验证上述各种算法的时间复杂度编写测试main()函数测试线性表的正确性。
2. 程序分析2.1 存储结构使用最简单的一维数组存储待排序的数据。
共使用三个数组,一个用来构造正序数组,一个是逆序数组,还有一个是随机数组。
每种排序使用的数组都是具有相同初始值的,因而使得试验结果具有可比较性。
2.2关键算法分析2.2.1 插入排序算法插入排序的思想是:每次从无序区取一元素将其添加到有序区中。
2.2.2希尔排序算法希尔排序是一种缩小增量排序的算法,首先将待排序元素集按照一定间隔分成多个子集,分别对这些子集进行直接插入排序,整个序列部分有序。
然后缩小间隔,在进行直接插入排序,直到间隔为1,此时,整个序列已全部有序。
2.2.3起泡排序起泡排序的思想是:两两比较相邻的元素,如果反序,则交换次序,直到没有反序的元素为止。
在此思想指导下①首先将待排序元素划分为有序区和无序区,初始状态有序区为空,无序区所有待排序素;②对无序区从前向后依次将相邻元素关键码进行比较,若反序,则交换③重复执行②直到无序区中没有元素。
2.2.4快速排序算法2,2,4,1一趟快速排序算法自然语言描述如下①选取区间第一个元素作为轴值②读取区间首尾坐标,并将其左右侧待比较元素③右侧扫描:从后向前找到第一个比轴值小的元素,和左侧待比较元素交换(左侧第一个带比较元素为轴值)④左侧扫描:从前向后找到第一个比轴值大的元素,和右侧待比较元素交换⑤重复②③,直到左右两侧带比较元素的坐标相等其c++描述如下2.2.4.2完整的快速排序算法如下:选择排序自然语言描述如下:①在r[1]~r[n]待排序元素序列中选出最小记录,将其与第一个元素r[n]交换②在r[2]~r[n]待排序元素序列中选出最小记录,将其与第一个元素r[i]交换…………③直至r[n-1]~r[n]C++描述如下:2.2.6堆排序2.2.6.1堆的建立,按照小根堆的定义建立堆的算法如下说明:根节点存放在r[1]中,r[i]的左孩子为r[2*i],右孩子为r[2*i+1]2.2.6.2调整数组为升序排列①输出堆顶元素②将堆中最后一个元素移至堆顶,并将剩余元素调整为小根堆③反复执行①②两个元素,直到堆中只有一个元素2.2.6.2堆排序完整算法如下3. 程序运行结果测试主函数运行流程图:开始初始化数组,计数器排序,输出比较次数和移动次数结束源代码#include<iostream>#include"time.h"using namespace std;void InsertSort(int r[], int n)//直接插入排序{int count1 = 0, count2 = 0;//分别用来记录插入排序比较和移动次数的计数器for (int i = 2; i <= n - 1; i++){if (r[i]<r[i - 1])//查找插入位置{r[0] = r[i]; //设置哨兵count2++; //移动次数加1int j;for (j = i - 1; count1++, r[0]<r[j]; j--) //寻找插入位置{r[j + 1] = r[j]; //元素后移count2++; //移动次数加1}r[j + 1] = r[0];//插入记录count2++;}else count1++;//此时虽然没有移动但是已经进行了一次比较}cout << "比较" << count1 << "移动" << count2;}void ShellSort(int r[], int n) //希尔排序{int i, d, 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)//每隔d个记录进行一次比较和移动r[j + d] = r[j]; //记录后移d个位置r[j + d] = r[0];count1++;count2 = count2 + d;//每次都移动d个位置}count1++;}cout << "比较" << count1 << "移动" << count2;}void BubbleSort(int r[], int n) //起泡排序{int temp, pos, bound;int count1 = 0, count2 = 0;pos = n - 1; //第一趟起泡排序的范围是r[1]到r[n]while (pos != 0) //仅当上一趟排序有记录交换才进行本趟排序{bound = pos; //本次无序元素的范围pos = 0; //控制外循环结束for (int j = 1; 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;pos = j; //记录每一次发生记录交换的位置当j=0时说明一次比较也没有了即已经全部有序了count2 = count2 + 3; //一个交换语句为一次移动共移动了次}}}cout << "比较" << count1 << "移动" << count2;}int Partition(int r[], int first, int end, int &count1, int &count2)//快速排序一次划分{int i = first; //初始化int j = end;int temp;while (i<j){while (i<j && r[i] <= r[j]){j--; //右侧扫描count1++;}if (i<j){temp = r[i];r[i] = r[j]; //将较小记录交换到前面r[j] = temp;i++;count2 = count2 + 3;count1++;}while (i<j && r[i] <= r[j]){i++; //左侧扫描count1++;}if (i<j){temp = r[i];r[i] = r[j]; //将较小记录交换到前面r[j] = temp; //将较大记录交换到后面j--;count2 = count2 + 3;count1++;}}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); //递归地对右侧子序列进行快速排序}}void SelectSort(int r[], int n)//简单选择排序{int i;int j;int index; //初始化int temp;int count1 = 0, count2 = 0;for (i = 1; i<n; i++) //对n个记录进行n-1趟简单选择排序{index = i; //假设index是最小的for (j = i + 1; j<n; j++) //在无序区中选取最小记录{if (r[j]<r[index]) //如果该元素比现在第i个位置的元素小index = j;//赋值给indexcount1++; //比较次数加一}//count1++; //在判断不满足循环条件j<n时比较了一次if (index != i){temp = r[i]; //将无序区的最小记录与第i个位置上的记录交换r[i] = r[index];r[index] = temp;count2 = count2 + 3; //移动次数加}}cout << "比较" << count1 << "移动" << count2;}void Sift(int r[], int k, int m, int &count1, int &count2)//小根堆筛选算法筛选法调整堆,s t分别为比较和移动次数,m为编号最大的叶子结点的编号{int i = k;int j = 2 * i + 1; //置i为要筛的结点j为i的左孩子int temp;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; //移动次数加}}}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[1..i]中最后一个记录相互交换r[i] = r[0];r[0] = temp; //完成一趟排序输出记录的次序状态Sift(r, 0, i - 1, count1, count2); //重建堆}cout << "比较" << count1 << "移动" << count2;}void Newarray(int a[], int b[])//产生顺序、逆序及随机数组{a[0] = 0;b[0] = 0;for (int s = 1; s<501; s++){a[s] = s; //顺序数组b[s] = 501 - s; //逆序数组}}void main(){srand(time(NULL));int c[501];c[0] = 0;cout << "随机数组: ";for (int s = 1; s < 501; s++){c[s] = rand() % 50 + 1;cout << c[s]<<" ";}const int num = 501; //赋值最大的数组的容量int a[num];int b[num];int c1[num];a[0] = 0;b[0] = 0;Newarray(a, b);cout << "顺序数组:";for (int j = 1; j<num; j++)cout << a[j] << " ";cout << endl;cout << "逆序数组:";for (int j = 1; j<num; j++)cout << b[j] << " ";cout << endl;cout << endl;cout << "排序方式" << " " << "正序" << " " << "逆序" << " " << "随机"<<endl<<endl;cout << "直接插入排序" << " ";Newarray(a, b);int count1 = 0, count2 = 0;InsertSort(a, num);cout << " ";InsertSort(b, num);cout << " ";InsertSort(c, num);count1 = 0, count2 = 0;cout << endl<<endl;cout << "希尔排序" << " ";Newarray(a, b);ShellSort(a, num);cout << " ";ShellSort(b, num);cout << " ";ShellSort(c, num);count1 = 0, count2 = 0;cout << endl<<endl;cout << "起泡排序" << " ";Newarray(a, b);BubbleSort(a, num);cout << " ";BubbleSort(b, num);cout << " ";BubbleSort(c, num);count1 = 0, count2 = 0;cout << endl<<endl;cout << "快速排序" << " ";Newarray(a, b);QuickSort(a, 0, num - 2, count1, count2);cout << "比较" << count1 << "移动" << count2 << " ";count1 = 0, count2 = 0;QuickSort(b, 0, num - 2, count1, count2);cout << "比较" << count1 << "移动" << count2 << " ";count1 = 0, count2 = 0;QuickSort(c, 0, num - 1, count1, count2);cout << "比较" << count1 << "移动" << count2 << endl<<endl;count1 = 0, count2 = 0;Newarray(a, b);cout << "简单选择排序"<<" ";SelectSort(a, num);cout << " ";SelectSort(b, num);cout << " ";SelectSort(c, num);cout << endl<<endl;Newarray(a, b);count1 = 0, count2 = 0;cout << "堆排序"<<" ";HeapSort(a, num);cout << " ";HeapSort(b, num);cout << " ";HeapSort(c, num);cout << endl;cout << "程序结束!";}。
数据结构排序实验报告
![数据结构排序实验报告](https://img.taocdn.com/s3/m/18e4c9b785868762caaedd3383c4bb4cf7ecb78c.png)
数据结构排序实验报告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. 实验结论根据实验结果,我们可以得出以下结论:- 冒泡排序和选择排序是简单但效率较低的排序算法,仅适用于较小规模的数据排序。
排序的实验报告
![排序的实验报告](https://img.taocdn.com/s3/m/a318b40dff4733687e21af45b307e87101f6f818.png)
排序的实验报告排序的实验报告引言:排序是计算机科学中常见的问题之一。
在实际应用中,我们经常需要对一组数据进行排序,以便更好地理解和分析数据。
本实验旨在比较不同排序算法的效率和性能,以及探讨它们在不同数据集上的表现。
实验设计:为了进行排序算法的比较,我们选择了五种常见的排序算法,分别是冒泡排序、选择排序、插入排序、快速排序和归并排序。
我们使用Python编程语言实现了这些算法,并在同一台计算机上运行它们以确保公平比较。
实验步骤:1. 数据集的准备我们选择了三种不同规模的数据集:小规模(100个元素)、中规模(1000个元素)和大规模(10000个元素)。
这些数据集包含了随机生成的整数。
2. 算法实现我们按照上述算法的描述,使用Python编程语言实现了这些排序算法。
为了确保准确性和效率,我们在实现过程中进行了多次测试和调试。
3. 实验运行我们分别对小规模、中规模和大规模的数据集运行这些排序算法,并记录下每个算法的运行时间。
实验结果:1. 小规模数据集排序结果对于小规模的数据集,所有的排序算法都能够在很短的时间内完成排序。
然而,快速排序和归并排序的运行时间明显短于冒泡排序、选择排序和插入排序。
2. 中规模数据集排序结果随着数据规模的增加,冒泡排序、选择排序和插入排序的运行时间显著增加,而快速排序和归并排序的运行时间仍然较短。
特别是在中规模数据集上,快速排序和归并排序的效率明显高于其他算法。
3. 大规模数据集排序结果在大规模数据集上,冒泡排序、选择排序和插入排序的运行时间急剧增加,而快速排序和归并排序的运行时间仍然保持在可接受的范围内。
这进一步证明了快速排序和归并排序的高效性。
讨论:通过对不同规模数据集的排序实验,我们可以得出以下结论:1. 快速排序和归并排序是最有效的排序算法,它们的运行时间相对较短。
2. 冒泡排序、选择排序和插入排序在小规模数据集上表现良好,但在大规模数据集上效率较低。
3. 对于特定的应用场景,选择合适的排序算法非常重要。
数据结构排序实验报告
![数据结构排序实验报告](https://img.taocdn.com/s3/m/2d7d05bfb8d528ea81c758f5f61fb7360b4c2b23.png)
数据结构排序实验报告数据结构排序实验报告实验目的:通过实践,掌握常见的数据结构排序算法的原理与实现方法,比较不同算法的时间复杂度与空间复杂度,并分析其优缺点。
实验环境:编程语言: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. 快速排序由于其递归调用栈的使用,时间复杂度虽然较低,但空间复杂度较高。
综上所述,选择排序、插入排序和冒泡排序适用于小规模数据排序,而归并排序、快速排序和堆排序适用于大规模数据排序。
数据结构实验报告——排序
![数据结构实验报告——排序](https://img.taocdn.com/s3/m/959493207375a417866f8faa.png)
数据结构实验报告排序姓名:13-计算机-舞学号:0000000000专业:计算机科学与技术班级:计算机13-2班日期:2014年6月6日星期五一、实验目的和要求通过编程实现直接插入排序、希尔排序、冒泡排序、快速排序、直接选择排序。
要求输入一些无序数,执行程序后使他们变成有序数并在窗口输出。
二、实验环境1、windows 72、c-free 5.0三、实验内容用五种排序算法对输入的数进行排序,并在屏幕中输出。
四、实验过程1、直接插入排序:即将所需要排序的数据分成两部分,其中一部分为已排好序部分,另一部分为未排序部分。
然后从未排序部分中选出一元素插入到一排序部分中,要求插入后已排序部分任然有序。
在编写该程序时,我将要排序的数据储存在一个数组中,并将第一个数划分为已经排序部分然后从下一个数开始不断和前边的最后一个数比较,知道找到插入位置。
2、希尔排序:希尔排序是建立在直接插入排序的基础之上的,他是通过将数据分成几组,在组内实现插入排序,使整个数据基本有序,最后再对整个数据实现插入排序。
这里同样将数据储存在数组中,分组的步长每次取之前步长的一半。
需要注意的是,移动元素时,下标不再是减1,而是减去步长。
3、冒泡排序:通过不断比较相邻的两个元素,发现倒序即交换,最终实现排序。
在这个程序中,我从后面开始向前比较。
每依次循环可以最终确定一个元素在其最终位置上,所以每次循环之后,元素间的两两比较次数减1.4、快速排序:选定一个元素作为中间元素,将整个数据分为比中间元素小的一组和比中间元素大的一组,并且小的在中间元素前,大的在中间元素后。
再分好的两组内再次重复上诉过程使所有元素排好序。
5、直接选择排序:将待排序数据存入数组中,扫描一遍数组,将其中最小的元素找出并放在第一位,再扫描一遍剩下的元素,找到最小的放在第二位。
如此不断重复知道扫描了n-1次。
由于不要再开新空间,所以找到最小元素时用交换的方式使其放在第一位。
比如第一遍扫描,假设第一个为最小元素,再扫描过程中,如果发现比它小的数,则把第一个元素和该位置的元素交换。
数据结构各种排序实验报告
![数据结构各种排序实验报告](https://img.taocdn.com/s3/m/7951f4e026fff705cc170aa1.png)
目录1.引言............................................................................................................................ 错误!未定义书签。
2.需求分析.................................................................................................................... 错误!未定义书签。
3.详细设计.................................................................................................................... 错误!未定义书签。
3.1 直接插入排序................................................................................................ 错误!未定义书签。
3.2折半排序......................................................................................................... 错误!未定义书签。
3.3 希尔排序........................................................................................................ 错误!未定义书签。
3.4简单选择排序................................................................................................. 错误!未定义书签。
《数据结构》实验报告——排序
![《数据结构》实验报告——排序](https://img.taocdn.com/s3/m/030478009b6648d7c0c7463d.png)
《数据结构》实验报告排序实验题目:输入十个数,从插入排序,快速排序,选择排序三类算法中各选一种编程实现。
实验所使用的数据结构内容及编程思路: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为止。
数据结构实验5报告-经典排序算法的实现
![数据结构实验5报告-经典排序算法的实现](https://img.taocdn.com/s3/m/5c777071b80d6c85ec3a87c24028915f804d84f6.png)
实验报告课程名称:数据结构与算法课程类型:必修实验项目:排序算法实验实验题目:经典排序算法的实现一、实验目的1.了解几种基本排序算法的思想2.实现几种基本的排序算法3.分析比较各种排序算法的时间复杂度4.更好深入理解各种排序算法二、实验要求及实验环境实验要求:实现以下四组排序算法中的任意三组:冒泡排序和快速排序;选择排序和堆排序。
插入排序和希尔排序;(二路)归并排序, 基数排序产生不同规模和分布的数据,以“图或表”的方式给出输入规模和分布对排序方法运行时间变化趋势的影响(画出T(n)的曲线)。
并与理论分析结果比较。
将上述“图或表”采用图片等形式贴在实验报告中,与作适当分析或说明。
实验环境:codeblocks/Dev-C++三、设计思想(本程序中的用到的所有数据抽象数据性ADT的定义,主程序的流程图及各程序模块之间的调用关系)1. 所用的抽象数据性ADT的定义1)逻辑结构:最大堆:是一种特殊形式的线性表,根节点的值总是大于叶节点的值。
堆的操作:按照最大堆整理堆:void pushdown(int first, int last);结构体数组:一个具有很多结构体元素的数组。
结构体数组的操作:产生待排序数组a:void createtest(records a[]);找到数组a基准元素下标:int findpivot(int i, int j);对数组a的元素a[i]......a[j]进行快速排序:void quicksort(int i, int j);打印排序数组:void print();2) 存储结构:定义了一个结构体数组records a[max].里面存有一个关键字值int key,表示每个节点的值。
对应的结构如图所示:具体函数实现:void createtest(records a[]){int i, j, temp,k;for (i = 1; i < 101; i++){a[i].key = i;//printf("%d %d ", k, test[k]);}for (k = 1; k < 10000; k++){i = rand() % max;j = rand() % max;if (i != 0 && j != 0){temp = a[i].key;a[i].key = a[j].key;a[j].key = temp;}}}//产生待排序数组avoid quicksort(int i, int j){int pivot;int k; //关键字大于等于pivot的记录在序列中的起始下标int pivotindex; //关键字为pivot的记录在数组A中的下标pivotindex = findpivot(i, j);if (pivotindex != 0){pivot = a[pivotindex].key;k = partition(i, j, pivot);quicksort(i, k - 1);quicksort(k, j);}}//对数组a的元素a[i]......a[j]进行快速排序int findpivot(int i, int j) //返回a[i],a[j]总较大关键字的下标,若全相同则返回0 {int firstkey = a[i].key;int k;for (k = i + 1; k <= j; k++) //从左到右查找不同的关键字{if (a[k].key > firstkey){return k;}else if (a[k].key < firstkey){return i;}}return 0;}//找到数组a基准元素下标void print(){for (int i = 1; i <= max-1; i++){printf("%d ",a[i].key);}}//打印排序数组2. 主程序流程图及各程序模块之间的调用关系流程图:调用关系:在输入操作数1~7后,分别调用:1. createtest(a); bubblesort(max - 1);2. createtest(a); quicksort(1, max - 1);3. createtest(a); selectsort(max - 1);4. createtest(a); heapsort(max - 1);5. createtest(a);insertsort(max-1);6. createtest(a);shellsort(max - 1);7. createtest(a); mergesort(max-1);四、测试结果(要求程序运行截图)1. 测试用例:一个结构体数组a[101],其关键字存有从1到100的乱序排列 2. 测试结果:五、经验体会与不足经验体会:1.要注意交换两个数的函数需要带取地址符,因为是对地址的操作,这样才能实现交换。
北邮数据结构实验报告-排序
![北邮数据结构实验报告-排序](https://img.taocdn.com/s3/m/3683ed5259fafab069dc5022aaea998fcc224088.png)
北邮数据结构实验报告-排序北邮数据结构实验报告-排序一、实验目的本实验旨在掌握常见的排序算法,包括冒泡排序、插入排序、选择排序、快速排序、归并排序等,并通过实际编程实现对数字序列的排序。
二、实验内容1.冒泡排序冒泡排序是一种简单的排序算法,其基本思想是依次比较相邻的两个元素,并按照从小到大或从大到小的顺序交换。
具体步骤如下:- 从待排序序列的第一个元素开始,依次比较相邻的两个元素;- 如果前面的元素大于后面的元素,则交换这两个元素的位置;- 重复上述步骤,直到整个序列有序。
2.插入排序插入排序是一种简单且直观的排序算法,其基本思想是将待排序序列分为已排序和未排序两部分,每次从未排序部分中选择一个元素插入到已排序部分的合适位置。
具体步骤如下:- 从待排序序列中选择一个元素作为已排序部分的第一个元素;- 依次将未排序部分的元素插入到已排序部分的合适位置,使得已排序部分保持有序;- 重复上述步骤,直到整个序列有序。
3.选择排序选择排序是一种简单且直观的排序算法,其基本思想是每次选择未排序部分中的最小(或最大)元素,并将其放在已排序部分的末尾。
具体步骤如下:- 在未排序部分中选择最小(或最大)的元素;- 将选择的最小(或最大)元素与未排序部分的第一个元素交换位置;- 重复上述步骤,直到整个序列有序。
4.快速排序快速排序是一种高效的排序算法,其基本思想是通过一趟排序将待排序序列分割成两部分,其中一部分的元素都比另一部分的元素小。
具体步骤如下:- 选择一个枢轴元素(一般选择第一个元素);- 将待排序序列中小于枢轴元素的元素放在枢轴元素的左侧,大于枢轴元素的元素放在枢轴元素的右侧;- 对枢轴元素左右两侧的子序列分别进行递归快速排序;- 重复上述步骤,直到整个序列有序。
5.归并排序归并排序是一种高效的排序算法,其基本思想是将待排序序列划分成足够小的子序列,然后对这些子序列进行两两合并,最终形成有序的序列。
具体步骤如下:- 将待排序序列递归地划分成足够小的子序列;- 对每个子序列进行归并排序;- 合并相邻的子序列,直到整个序列有序。
数据结构排序算法实验报告
![数据结构排序算法实验报告](https://img.taocdn.com/s3/m/0d5c3e047cd184254b353550.png)
移动次数 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,再进行初始建堆,直至完全排好序。
山东大学数据结构实验报告四
![山东大学数据结构实验报告四](https://img.taocdn.com/s3/m/dcd9d4ba8662caaedd3383c4bb4cf7ec4afeb6df.png)
山东大学数据结构实验报告四实验报告四:堆排序算法的设计与实现一、引言堆排序是一种基于二叉堆的排序算法,其具有时间复杂度为O(nlogn)的特点,适用于大规模数据的排序。
本实验旨在通过设计与实现堆排序算法,掌握堆排序的原理和实现过程,并分析其时间复杂度和空间复杂度。
二、实验目的1. 理解堆排序的基本原理;2. 掌握堆排序算法的实现过程;3. 分析堆排序算法的时间复杂度和空间复杂度。
三、实验内容1. 设计堆排序算法的流程;2. 根据设计的流程,编写堆排序算法的代码;3. 使用随机生成的数据进行测试,并记录排序结果;4. 分析堆排序的时间复杂度和空间复杂度。
四、实验步骤1. 设计堆排序算法的流程:1.1 创建一个最大堆(Max Heap);1.2 将堆顶元素与最后一个元素交换;1.3 对剩余元素进行堆调整,使其满足最大堆的性质;1.4 重复步骤2和3,直到所有元素排序完成。
2. 根据设计的流程,编写堆排序算法的代码:```java// 堆排序算法public class HeapSort {public static void sort(int[] arr) {int n = arr.length;// 构建最大堆for (int i = n / 2 - 1; i >= 0; i--)heapify(arr, n, i);// 依次将堆顶元素与最后一个元素交换,并重新调整堆 for (int i = n - 1; i >= 0; i--) {int temp = arr[0];arr[0] = arr[i];arr[i] = temp;heapify(arr, i, 0);}}// 调整堆public static void heapify(int[] arr, int n, int i) {int largest = i; // 最大元素的索引int left = 2 * i + 1; // 左子节点的索引int right = 2 * i + 2; // 右子节点的索引// 如果左子节点比最大元素大,则更新最大元素的索引if (left < n && arr[left] > arr[largest])largest = left;// 如果右子节点比最大元素大,则更新最大元素的索引if (right < n && arr[right] > arr[largest])largest = right;// 如果最大元素的索引不是当前节点,则交换当前节点和最大元素,并继续调整堆if (largest != i) {int swap = arr[i];arr[i] = arr[largest];arr[largest] = swap;heapify(arr, n, largest);}}}```3. 使用随机生成的数据进行测试,并记录排序结果:```javapublic class Main {public static void main(String[] args) {int[] arr = generateRandomData(100); // 生成100个随机数 System.out.println("排序前:");printArray(arr);HeapSort.sort(arr); // 使用堆排序算法进行排序System.out.println("排序后:");printArray(arr);}// 生成随机数据public static int[] generateRandomData(int n) {int[] arr = new int[n];Random random = new Random();for (int i = 0; i < n; i++) {arr[i] = random.nextInt(1000);}return arr;}// 打印数组public static void printArray(int[] arr) {for (int i : arr) {System.out.print(i + " ");}System.out.println();}}```排序前:567 245 789 123 456 789 234 567 890 123 ...排序后:1 2 3 4 5 6 7 8 9 10 ...4. 分析堆排序的时间复杂度和空间复杂度:- 时间复杂度:堆排序的建堆过程的时间复杂度为O(n),每次调整堆的时间复杂度为O(logn),共需要调整n-1次。
数据结构排序实验报告
![数据结构排序实验报告](https://img.taocdn.com/s3/m/a94e67b00875f46527d3240c844769eae109a366.png)
数据结构排序实验报告一、实验目的本次实验的主要目的是深入理解和掌握常见的数据结构排序算法,并通过实际编程实现和性能分析,比较不同排序算法在不同数据规模和特征下的效率和优劣。
二、实验环境本次实验使用的编程语言为 Python,开发环境为 PyCharm。
实验所使用的计算机配置为:处理器_____,内存_____,操作系统_____。
三、实验内容1、冒泡排序(Bubble Sort)冒泡排序是一种简单的排序算法。
它重复地走访要排序的数列,一次比较两个数据元素,如果顺序不对则进行交换,并一直重复这样的走访操作,直到没有要交换的数据元素为止。
以下是冒泡排序的 Python 代码实现:```pythondef bubble_sort(arr):n = len(arr)for i in range(n):for j in range(0, n i 1):if arrj > arrj + 1 :arrj, arrj + 1 = arrj + 1, arrj```2、选择排序(Selection Sort)选择排序首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
以此类推,直到所有元素均排序完毕。
选择排序的 Python 代码如下:```pythondef selection_sort(arr):for i in range(len(arr)):min_idx = ifor j in range(i + 1, len(arr)):if arrmin_idx > arrj:min_idx = jarri, arrmin_idx = arrmin_idx, arri```3、插入排序(Insertion Sort)插入排序是一种简单直观的排序算法。
它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入,直到未排序数据为空。
数据结构实验报告排序
![数据结构实验报告排序](https://img.taocdn.com/s3/m/b599ff740a4c2e3f5727a5e9856a561252d32199.png)
数据结构实验报告排序数据结构实验报告:排序引言:排序是计算机科学中常见的算法问题之一,它的目标是将一组无序的数据按照特定的规则进行排列,以便于后续的查找、统计和分析。
在本次实验中,我们将学习和实现几种常见的排序算法,并对它们的性能进行比较和分析。
一、冒泡排序冒泡排序是最简单的排序算法之一,它通过不断交换相邻的元素,将较大(或较小)的元素逐渐“冒泡”到数组的一端。
具体实现时,我们可以使用两层循环来比较和交换元素,直到整个数组有序。
二、插入排序插入排序的思想是将数组分为两个部分:已排序部分和未排序部分。
每次从未排序部分中取出一个元素,插入到已排序部分的适当位置,以保持已排序部分的有序性。
插入排序的实现可以使用一层循环和适当的元素交换。
三、选择排序选择排序每次从未排序部分中选择最小(或最大)的元素,与未排序部分的第一个元素进行交换。
通过不断选择最小(或最大)的元素,将其放置到已排序部分的末尾,从而逐渐形成有序序列。
四、快速排序快速排序是一种分治的排序算法,它通过选择一个基准元素,将数组划分为两个子数组,其中一个子数组的所有元素都小于等于基准元素,另一个子数组的所有元素都大于基准元素。
然后对两个子数组分别递归地进行快速排序,最终将整个数组排序。
五、归并排序归并排序也是一种分治的排序算法,它将数组划分为多个子数组,对每个子数组进行排序,然后再将排好序的子数组合并成一个有序的数组。
归并排序的实现可以使用递归或迭代的方式。
六、性能比较与分析在本次实验中,我们对以上几种排序算法进行了实现,并通过对不同规模的随机数组进行排序,比较了它们的性能。
我们使用了计算排序时间的方式,并记录了每种算法在不同规模下的运行时间。
通过对比实验结果,我们可以得出以下结论:1. 冒泡排序和插入排序在处理小规模数据时表现较好,但在处理大规模数据时性能较差,因为它们的时间复杂度为O(n^2)。
2. 选择排序的时间复杂度也为O(n^2),与冒泡排序和插入排序相似,但相对而言,选择排序的性能稍好一些。
最新实验四排序实验报告
![最新实验四排序实验报告](https://img.taocdn.com/s3/m/b1f7f3780a4c2e3f5727a5e9856a561253d32167.png)
最新实验四排序实验报告实验目的:1. 理解并掌握四种基本排序算法:冒泡排序、选择排序、插入排序和快速排序的工作原理及其性能特点。
2. 通过编程实践,加深对算法效率和适用场景的理解。
3. 培养分析问题和解决问题的能力,提高编程技巧。
实验环境:- 操作系统:Windows 10- 编程语言:Python 3.8- 开发工具:PyCharm实验内容:1. 编写冒泡排序算法实现对一组随机整数的排序。
2. 实现选择排序算法,并对同样的一组随机整数进行排序。
3. 完成插入排序算法的编码,并用相同的数据集进行测试。
4. 编写快速排序算法,并比较其与其他三种排序算法的效率。
5. 分析比较不同排序算法在最坏、平均和最好情况下的时间复杂度。
实验步骤:1. 首先,生成一组包含50个随机整数的数据集。
2. 对于冒泡排序,重复交换相邻的元素,如果前者大于后者,则进行交换。
3. 对于选择排序,遍历数组,找到最小(或最大)的元素,将其与第一个元素交换,然后从剩下的元素中继续寻找最小(或最大)的元素,依此类推。
4. 插入排序的实现是将数组分为已排序和未排序两部分,每次从未排序部分取出一个元素,插入到已排序部分的适当位置。
5. 快速排序通过选定一个基准值,将数组分为两部分,一部分的元素都小于基准值,另一部分的元素都大于基准值,然后递归地在两部分上重复这个过程。
6. 使用计时器分别记录四种排序算法的执行时间,并进行比较分析。
实验结果:- 冒泡排序:平均时间复杂度为O(n^2),在实验数据集上的执行时间为X秒。
- 选择排序:平均时间复杂度为O(n^2),在实验数据集上的执行时间为Y秒。
- 插入排序:平均时间复杂度为O(n^2),在实验数据集上的执行时间为Z秒。
- 快速排序:平均时间复杂度为O(n log n),在实验数据集上的执行时间为W秒。
实验结论:通过实验,我们发现快速排序在大多数情况下都比其他三种简单排序算法有更高的效率。
冒泡排序、选择排序和插入排序在最坏情况下的时间复杂度都较高,适合处理小规模数据集或者基本有序的数据。
实现排序算法的实验报告
![实现排序算法的实验报告](https://img.taocdn.com/s3/m/a6327c9a09a1284ac850ad02de80d4d8d05a0112.png)
一、实验目的1. 理解排序算法的基本原理和特点。
2. 掌握几种常用的排序算法(冒泡排序、选择排序、插入排序、快速排序、归并排序等)的实现方法。
3. 分析不同排序算法的时间复杂度和空间复杂度。
4. 通过实际编程实现排序算法,提高编程能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.83. 开发工具:PyCharm三、实验内容1. 冒泡排序2. 选择排序3. 插入排序4. 快速排序5. 归并排序四、实验步骤1. 冒泡排序(1)编写冒泡排序函数:def bubble_sort(arr)。
(2)输入测试数据:arr = [5, 3, 8, 4, 1]。
(3)调用冒泡排序函数:bubble_sort(arr)。
(4)输出排序后的结果:print(arr)。
2. 选择排序(1)编写选择排序函数:def selection_sort(arr)。
(2)输入测试数据:arr = [5, 3, 8, 4, 1]。
(3)调用选择排序函数:selection_sort(arr)。
(4)输出排序后的结果:print(arr)。
3. 插入排序(1)编写插入排序函数:def insertion_sort(arr)。
(2)输入测试数据:arr = [5, 3, 8, 4, 1]。
(3)调用插入排序函数:insertion_sort(arr)。
(4)输出排序后的结果:print(arr)。
4. 快速排序(1)编写快速排序函数:def quick_sort(arr)。
(2)输入测试数据:arr = [5, 3, 8, 4, 1]。
(3)调用快速排序函数:quick_sort(arr)。
(4)输出排序后的结果:print(arr)。
5. 归并排序(1)编写归并排序函数:def merge_sort(arr)。
(2)输入测试数据:arr = [5, 3, 8, 4, 1]。
(3)调用归并排序函数:merge_sort(arr)。
数据结构中查找和排序算法实验报告
![数据结构中查找和排序算法实验报告](https://img.taocdn.com/s3/m/c63c1b4b3b3567ec102d8a8b.png)
mergesort(ListType &r,ListType &r1,int s,int t)
{
if (s==t)
r1[s]=r[s];
else
{
mergesort(r,r2,s,s+t/2);
mergesort(r,r2,s+t/2+1,t);
merge(r2,s,s+t/2,t,r1);
}
}
4.堆排序算法描述如下:
堆排序要解决两个问题:1、如何由一个无序序列建成一个堆?2、如何在输出堆顶元素之后,调整剩余元素成为一个新的堆?
问题2的解决方法:
四.实验数据与清单:
1.折半查找算法描述如下:
int Search_Bin(SSTable ST,KeyType key)
low=1;high=ST.length;
while(low<=high){
sift(ListType &r,int k,int m)
{
i=k;j=2*i;x=r[k].key;finished=FALSE;
t=r[k];
while((j<=m)&&(!finished))
{
if ((j<m)&&(r[j].key>r[j+1].key)) j++;
if (x<=r[j].key)
通过本次实验,我了发现书本上的知识和老师的讲解都能慢慢理解。但是做实验的时候,需要我把理论变为上机调试,这无疑是最难的部分,有时候我想不到合适的算法去解决问题,就请教同学,上网搜索,逐渐纠正了自己的错误。这次的程序设计对我的编程设计思维有很大的提高,以前我很不懂这门课,觉得它很难,但是现在明白了一些代码的应用,明白了每个程序都有相似的特点,通用的结构,也学会了静下心来写程序。我以后还要把没学好的知识点补齐,克服编程过程中的难关,打实基础,向更深入的层次发展。
数据结构实验报告——排序
![数据结构实验报告——排序](https://img.taocdn.com/s3/m/e4b25b94dd88d0d233d46a5c.png)
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、归并排序:将若干个有序序列两两归并,直至所有待排序的记录都在一个有序序列为止。
数据结构课程设计排序实验报告
![数据结构课程设计排序实验报告](https://img.taocdn.com/s3/m/b2dd1cdda0116c175f0e4852.png)
《数据结构》课程设计报告专业班级姓名学号指导教师起止时间课程设计:排序综合一、任务描述利用随机函数产生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()(三)函数调用关系程序的主要结构(函数调用关系)如下图所示。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构实验报告记录(四):实现典型的排序算法————————————————————————————————作者:————————————————————————————————日期:佛山科学技术学院实验报告课程名称数据结构实验项目实现典型的排序算法专业班级 10网络工程2 姓名张珂卿学号 2010394212指导教师成绩日期 2011.11.27一、实验目的1.掌握排序的基本概念;2.熟悉排序中使用的存储结构,掌握多种排序算法,如堆排序、希尔排序、快速排序算法等。
二、实验内容1.几种典型的排序算法;2.计算不同的排序算法的时间复杂度;3.判定某种排序算法是否稳定的标准。
三、实验原理排序是计算机内经常进行的一种操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列。
分内部排序和外部排序。
若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序。
反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序。
内部排序的过程是一个逐步扩大记录的有序序列长度的过程。
四、实验步骤1.输入记录的基本结点与信息,选用相关的存储结构,完成记录的存储、输入的初始化工作。
2.选择“直接插入排序”,“希尔排序”,“快速排序”,“简单选择排序”和“堆排序”几种排序中的任意三种排序,编程实现排序算法。
用菜单形式选择排序方法,并显示排序过程和排序结果。
3.计算排序算法的时间复杂度并进行稳定性分析。
五、程序源代码及注释#include"iostream"using namespace std;#define MAX_NO_OF_KEY 8#define RADIX 10 //关键字基数#define MAX_SPACE 1000typedef struct{int keys[MAX_NO_OF_KEY];//关键字int data;//其他数据项int next;}SLCell;typedef struct{SLCell r[MAX_SPACE];//静态链表可利用空间int keynum;//记录的当前关键字个数int recnum;//静态链表的当前长度}SLList;typedef int ArrType[RADIX];//指针数组类型int len;//数组长度//插入排序void DirectInsertSort(int Elem_Arr[]){int i,j;for(i=2;i<len;i++){Elem_Arr[0]=Elem_Arr[i];for(j=i-1;j>=1;j--)if(Elem_Arr[0]<Elem_Arr[j])Elem_Arr[j+1]=Elem_Arr[j];elsebreak;Elem_Arr[j+1]=Elem_Arr[0];}}//希尔排序void ShellInsert(int Elem_Arr[],int add)//add为某趟希尔排序的增量{int i,j;for(i=add+1;i<len;i++){Elem_Arr[0]=Elem_Arr[i];for(j=i-add;j>0&&Elem_Arr[j]>Elem_Arr[0]; j-=add)Elem_Arr[j+add]=Elem_Arr[j];Elem_Arr[j+add]=Elem_Arr[0];}}void ShellSort(int Elem_Arr[]){int t;cout<<"请输入增量数组元素个数:"<<endl;cin>>t;int *dlta=new int[t];cout<<"请依次输入增量数组元素:"<<endl;for(int i=0;i<t;i++)cin>>dlta[i];for(int k=0;k<t;++k)ShellInsert(Elem_Arr,dlta[k]);//一趟增量为dlta[k]的插入排序}//快速排序int Partition(int Elem_Arr[],int i,int j)//实现一分为二,pivotkey为枢轴变量{int pivotkey;pivotkey=Elem_Arr[i];while(i<j){while(i<j&&Elem_Arr[j]>=pivotkey)--j;Elem_Arr[i]=Elem_Arr[j];while(i<j&&Elem_Arr[i]<=pivotkey)++i;Elem_Arr[j]=Elem_Arr[i];}Elem_Arr[i]=pivotkey;return i;}//Partitionvoid QSort(int Elem_Arr[],int low,int high){int pivotloc;if(low<high){QSort(Elem_Arr,low,pivotloc-1);QSort(Elem_Arr,pivotloc+1,high);}}void QuickSort(int Elem_Arr[]){QSort(Elem_Arr,1,len-1);}//简单选择排序int SelectMin(int Elem_Arr[],int i){int min=i;for(int j=i+1;j<len;j++)if(Elem_Arr[min]>Elem_Arr[j])min=j;return min;}void SelectSort(int Elem_Arr[]){int t,j;for(int i=1;i<len;++i){j=SelectMin(Elem_Arr,i);if(i!=j){t=Elem_Arr[i];Elem_Arr[i]=Elem_Arr[j];Elem_Arr[j]=t;}}}//SelectSort//堆排序void HeapAdjust(int Elem_Arr[],int i,int m) {Elem_Arr[0]=Elem_Arr[i];for(int j=2*i;j<=m;j*=2){if(j<m&&Elem_Arr[j]<Elem_Arr[j+1])++j;if(Elem_Arr[0]>Elem_Arr[j])break;i=j;}Elem_Arr[i]=Elem_Arr[0];}void HeapSort(int Elem_Arr[]){for(int i=(len-1)/2;i>0;--i)HeapAdjust(Elem_Arr,i,len-1);for(i=len-1;i>1;--i){Elem_Arr[0]=Elem_Arr[i];Elem_Arr[i]=Elem_Arr[1];Elem_Arr[1]=Elem_Arr[0];HeapAdjust(Elem_Arr,1,i-1);}}//归并排序void Merge(int Elem_Arr1[],int Elem_Arr[],int i,int m,int n) //将有序的SR[i..m]和SR[m+1..n]归并为有序的TR[i..n]{int j,k;for(j=m+1,k=i;i<=m&&j<=n;++k){//将SR中记录由小到大地并入TRif(Elem_Arr1[i]<Elem_Arr1[j])Elem_Arr[k]=Elem_Arr1[i++];elseElem_Arr[k]=Elem_Arr1[j++];}if(i<=m) //TR[k..n]=SR[i..m];将剩余的SR[i..m]复制到TRwhile(k<=n&&i<=m)Elem_Arr[k++]=Elem_Arr1[i++];if(j<=n) //将剩余的SR[j..n]复制到TRwhile(k<=n&&j<=n)Elem_Arr[k++]=Elem_Arr1[j++];}void MSort(int Elem_Arr1[],int Elem_Arr[],int s,int t) //将SR[s..t]归并排序为TR1[s..t]{int m;int TR2[20];if(s==t)else{m=(s+t)/2; //将SR[s..t]平分为SR[s..m]和SR[m+1..t]MSort(Elem_Arr1,TR2,s,m); //递归地将SR[s..m]归并为有序的TR2[s..m] MSort(Elem_Arr1,TR2,m+1,t); //将SR[m+1..t]归并为有序的TR2[m+1..t]Merge(TR2,Elem_Arr,s,m,t); //将TR2[s..m]和TR2[m+1..t]归并到TR1[s..t] }}void MergeSort(int Elem_Arr[]) //对顺序表L作归并排序。
{int *Elem_Arr1=new int [len];for(int i=0;i<len;i++)Elem_Arr1[i]=Elem_Arr[i];MSort(Elem_Arr1,Elem_Arr,1,len-1);}//基数排序int succ(int f[],int j){int k=j;for(j;j<10;j++)if(f[j]!=0) break;else k++;if(j<10) return k;else return 0;}void CreateL(SLList &L){cout<<"请依次输入元素:"<<endl;for(int i=1;i<=L.recnum;i++){cin>>L.r[i].data;L.r[i].keys[0]=L.r[i].data%10;L.r[i].keys[1]=(L.r[i].data%100-L.r[i].keys[0])/10;L.r[i].keys[2]=L.r[i].data/100;}}void Distribute(SLList &L,int i,ArrType &f,ArrType &e){// 算法10.15// 本算法按第i个关键字keys[i]建立RADIX个子表,// 使同一子表中记录的keys[i]相同。