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

合集下载

排序的实验报告范文

排序的实验报告范文

排序的实验报告范文数据结构实验报告实验名称:实验四排序学生姓名:班级:班内序号:学号:日期: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. 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、如此循环到只剩最后两个比较,即得到排好序的一组数。

相关文档
最新文档