北邮数据结构实验报告实验四排序含源码
数据结构实验报告实验4

数据结构实验报告实验名称:实验四排序(题目1)学生姓名:班级:班内序号:学号:日期:2013年12月19日1.实验要求实验目的:学习、实现、对比各种排序算法,掌握各种排序算法的优劣,以及各种算法使用的情况。
实验内容:使用简单数组实现下面各种排序算法,并进行比较。
排序算法:1、插入排序2、希尔排序3、冒泡排序4、快速排序5、简单选择排序6、堆排序7、其他要求:1、测试数据分成三类:正序、逆序、随机数据2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。
3、对2的结果进行分析,验证上述各种算法的时间复杂度。
编写测试main()函数测试线性表的正确性。
2. 程序分析2.1 存储结构程序采用的存储机构是顺序存储,如下图所示:2.2 关键算法分析2.2.1 插入排序插入排序的基本方法是寻找一个指定元素在待排序元素中的位置,然后插入。
一趟直接插入排序的C++描述过程如下:①将待插入纪录赋值给哨兵r[0]:r[0]=r[i];②从后向前进行顺序查找:for(j=i-1;r[0]<r[j];j--);③元素后插:r[j+1]=r[j];④插入记录:r[j+1]=r[j];性能分析:原序列正序时直接插入排序达到最好的时间性能,比较次数为n-1,移动次数为0。
原序列逆序时直接插入排序达到最差时间性能,比较次数为,移动次数为。
直接插入排序的平均时间复杂度为,空间复杂度为。
直接插入排序是一种稳定的排序算法,特别适合于待排序集合基本有序的情况。
2.2.2 希尔排序希尔排序的基本方法是将待排序的元素集分成多个子集,分别对这些子集进行直接插入排序,待整个序列基本有序时,再对元素进行一次直接插入排序。
希尔排序的整个过程如下:for(int d=n/2;d>=1;d=d/2) //以d为增量//在子序列中进行插入排序{for(int i=d+1;i<=n;i++) //一趟希尔排序{if(r[i]<r[i-d]){r[0]=r[i];for(int j=i-d;j>0&&r[0]<r[j];j=j-d)//每隔d个记录,进行一次比较和移动,d=1时即是最后一趟直接插入排序r[j+d]=r[j];r[j+d]=r[0];}}}性能分析:希尔排序的时间复杂度在和之间,空间复杂度为,是一种不稳定的排序算法。
数据结构与算法实验报告及代码-内排序

实验五内排序1.实验目的(1)掌握在数组上进行各种排序的方法和算法(2)加深对排序的理解,逐步培养解决实际问题的编程能力2.实验内容(1)完成直接插入排序算法(2)完成起泡(冒泡)排序算法3.实验重点熟悉和掌握数组上各种排序方法和算法4. 实验难点掌握数组上各种排序方法和算法5.实验指导参考程序代码如下:(1)/*****************************************//* 直接插入排序算法 *//*****************************************/InsertSort.hvoid InsertSort (DataType a[], int n)//用直接插入法对a[0]--a[n-1]排序{int i, j;DataType temp;for(i=0; i<n-1; i++){temp = a[i+1];j = i;while(j > -1 && temp.key < a[j].key){a[j+1] = a[j];j--;}a[j+1] = temp;}}InsertSort.cpp#include <iostream>using namespace std;typedef int KeyType;struct DataType{KeyType key;};#include "InsertSort.h"void main(void){DataType test[6]={64,5,7,89,6,24};int n = 6;InsertSort(test,n);for(int i=0; i<n; i++)cout << test[i].key << " "; system("pause");}/*****************************************/ /* 冒泡排序算法 */ /*****************************************/ datatype.htypedef int keytype;struct datatype{keytype key;};BubbleSort.cpp#include <iostream>using namespace std;#include"datatype.h"void BubbleSort(datatype a[], int n)//用冒泡排序法对a[0]--a[n-1]排序{int i, j, flag=1;datatype temp;for(i = 1; i < n && flag == 1; i++){flag = 0;for(j = 0; j < n-i; j++){if(a[j].key > a[j+1].key){flag = 1;temp = a[j];a[j] = a[j+1];a[j+1] = temp;}}}}void main(void){datatype test[6]={64,5,7,89,6,24};int n = 6;BubbleSort(test,n);for(int i=0; i<n; i++)cout << test[i].key << " "; system("pause");}。
数据结构实验四题目一排序实验报告

数据结构实验报告实验名称:实验四——排序学生:XX班级:班序号:学号:日期:1.实验要求实验目的:通过选择实验容中的两个题目之一,学习、实现、对比、各种排序的算法,掌握各种排序算法的优劣,以及各种算法使用的情况。
题目1:使用简单数组实现下面各种排序算法,并进行比较。
排序算法如下:1、插入排序;2、希尔排序;3、冒泡排序;4、快速排序;5、简单选择排序;6、堆排序;7、归并排序;8、基数排序(选作);9、其他。
具体要求如下:1、测试数据分成三类:正序、逆序、随机数据。
2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换记为3次移动)。
3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微妙。
4、对2和3的结果进行分析,验证上述各种算法的时间复杂度。
5、编写main()函数测试各种排序算法的正确性。
2. 程序分析2.1 存储结构存储结构:数组2.2 关键算法分析一、关键算法:1、插入排序a、取排序的第二个数据与前一个比较b、若比前一个小,则赋值给哨兵c、从后向前比较,将其插入在比其小的元素后d、循环排序2、希尔排序a、将数组分成两份b、将第一份数组的元素与哨兵比较c、若其大与哨兵,其值赋给哨兵d、哨兵与第二份数组元素比较,将较大的值赋给第二份数组e、循环进行数组拆分3、对数据进行编码a、取数组元素与下一个元素比较b、若比下一个元素大,则与其交换c、后移,重复d、改变总元素值,并重复上述代码4、快速排序a、选取标准值b、比较高低指针指向元素,若指针保持前后顺序,且后指针元素大于标准值,后指针前移,重新比较c、否则后面元素赋给前面元素d、若后指针元素小于标准值,前指针后移,重新比较e、否则前面元素赋给后面元素5、简单选择排序a、从数组中选择出最小元素b、若不为当前元素,则交换c、后移将当前元素设为下一个元素6、堆排序a、生成小顶堆b、将堆的根节点移至数组的最后c、去掉已做过根节点的元素继续生成小顶堆d、数组倒置7、归并排序a、将数组每次以1/2拆分,直到为最小单位b、小相邻单位数组比较重排合成新的单位c、循环直至完成排序二、代码详细分析:1、插入排序关键代码:①取排序的第二个数据与前一个比较:if(r[i]<r[i-1])②若比前一个小,则赋值给哨兵:r[0]=r[i];③从后向前比较,将其插入在比其小的元素后:for(j=i-1;r[0]<r[j];j--){r[j+1]=r[j];a++;} r[j+1]=r[0];④循环排序2、希尔排序关键代码:①将数组分成两份:d=n/2②将第一份数组的元素与哨兵比较:for(int i=d+1;i<=n;i++)③若其大与哨兵,其值赋给哨兵:if(r[0]<r[i-d]){ r[0]=r[i];}④哨兵与第二份数组元素比较,将较大的值赋给第二份数组:for(j=i-d;j>0&&r[0]<r[j];j=j-d) {r[j+d]=r[j]; }⑤循环进行数组拆分:for(int;d>=1;d=d/2)3、冒泡排序关键代码:①取数组元素与下一个元素比较: for(int i=1;i<bound;i++)if(r[i]>r[i+1])②若比下一个元素大,则与其交换: r[0]=r[i]; r[i]=r[i+1]; r[i+1]=r[0];③后移,重复:for(int i=1;i<bound;i++)④改变总元素值,并重复上述代码:int bound=pos;4、快速排序关键代码:①选取标准值:r[0]=r[i]②比较高低指针指向元素,若指针保持前后顺序,且后指针元素大于标准值,后指针前移,重新比较:while(i<j&&r[j]>=flag) {j--;}③否则后面元素赋给前面元素:r[i]=r[j];④若后指针元素小于标准值,前指针后移,重新比较:while(i<j&&r[i]<=flag){i++;}⑤否则前面元素赋给后面元素:r[j]=r[i];5、简单选择排序关键代码:①从数组中选择出最小元素: for(int j=i+1;j<=n;j++)②{if(r[j]<r[index]) index=j; }③若不为当前元素,则交换:if(index!=i) {r[0]=r[i]; r[i]=r[index];r[index]=r[0];}④后移将当前元素设为下一个元素:for(int i=1;i<n;i++)6、堆排序关键代码:①生成小顶堆:while(j<=m) {if(j<m&&r[j]>r[j+1]) {j++;}②if(r[i]<r[j]) {break; }③else{ int x; x=r[i]; r[i]=r[j]; r[j]=x; i=j; j=2*i; }}④将堆的根节点移至数组的最后: x=r[1]; r[1]=r[n-i+1]; r[n-i+1]=x;⑤去掉已做过根节点的元素继续生成小顶堆:sift(r,1,n-i,x,y);⑥数组倒置输出: for(int i=n;i>0;i--)cout<<r[i]<<" ";7、归并排序关键代码:①将数组每次以1/2拆分,直到为最小单位: mid=(low+high)/2;②小相邻单位数组比较重排合成新的单位:while(i<=m&&j<=high)if(L.r[i]<=L.r[j]) t[k++]=L.r[i++];else t[k++]=L.r[j++];while(i<=m) t[k++]=L.r[i++];while(j<=high) t[k++]=L.r[j++];for(i=low,k=0;i<=high;i++,k++) L.r[i]=t[k];三、计算关键算法的时间、空间复杂度插入排序O(n2)希尔排序O(n2)冒泡排序O(n2)快速排序O(nlog2n)简单选择排序O(n2)堆排序O(nlog2n)归并排序O(nlog2n)3. 程序运行结果1、测试主函数流程:流程图如图所示流程图示意图程序运行结果图如下:2、测试条件:按题目要求分别输入同组数据的正序、逆序、随机序列进行测试。
北邮数据结构实验四-链表排序

数据结构实验报告实验名称:实验四——链表的排序学生姓名:班级:班内序号:学号:日期:1.实验要求[内容要求]使用链表实现下面各种排序算法,并进行比较。
排序算法:1、插入排序2、冒泡排序3、快速排序4、简单选择排序5、其他要求:1、测试数据分成三类:正序、逆序、随机数据2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。
3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)4、对2和3的结果进行分析,验证上述各种算法的时间复杂度编写测试main()函数测试线性表的正确性代码要求1、必须要有异常处理,比如删除空链表时需要抛出异常;2、保持良好的编程的风格:代码段与段之间要有空行和缩近标识符名称应该与其代表的意义一致函数名之前应该添加注释说明该函数的功能关键代码应说明其功能3、递归程序注意调用的过程,防止栈溢出2. 程序分析2.1 存储结构[内容要求]存储结构:双链表2.2 关键算法分析[内容要求]定义类:template <class T>class LinkList{public:LinkList(){front = new Node <T>;front->next=rear;front->prior=NULL;rear=newNode<T>;rear->next=NULL;rear->prior=front;}LinkList(T a[],int n);void BackLinkList(T a[]);//恢复原链表~LinkList();//析构函数void PrintList();//打印数列void InsertSort();//插入排序void BubbleSort();//冒泡排序Node <T>* Partion(Node <T> *i,Node <T> *j);//快速排序中寻找轴值的函数void Qsort(Node <T> *i,Node <T> *j);//快速排序void SelectSort();//选择排序Node<T>*front;Node<T>*rear;};成员函数包括:构造函数:单链表,打印单链表,插入排序,快速排序,冒泡排序,选择排序,析构函数公有成员:头指针和尾指针1、构造函数:LinkList<T>::LinkList(T a[],int n){front=new Node<T>;rear=new Node<T>;front->prior=NULL;front->next=rear;rear->next=NULL;rear->prior=front;Node <T>*s;for (int i=n-1;i>=0;i--){s=new Node<T>;s->data=a[i];s->next=front->next;front->next=s;s->prior=front;s->next->prior=s;}}2、析构函数LinkList<T>::~LinkList(){Node<T> *p=front->next;while(p->next!=NULL){delete p->prior;p=p->next;}delete rear;front=NULL;rear=NULL;}3、打印函数template <class T>void LinkList<T>::PrintList(){Node<T> *p=front->next;while(p->next!=NULL){cout<<p->data<<" ";p=p->next;}cout<<endl;}4、插入排序template <class T>void LinkList<T>::InsertSort(){Node<T> *p=front->next->next;Node<T> *q;T temp;while (p->next!=NULL){if (p->data<p->prior->data){temp=p->data;MoveCount++;q=p->prior;while (temp<q->data){q->next->data=q->data;q=q->prior;CompareCount++;MoveCount++;}q->next->data=temp;MoveCount++;}CompareCount++;p=p->next;}}将链表分为有序区和无序区,分别将无序区的每一个元素插入到有序区的相应位置。
北邮数据结构实验报告实验四

2009级数据结构实验报告实验名称:实验四——排序学生姓名:班级:班内序号:学号:日期:2010/12/171.实验要求实验目的:通过选择下面两个题目之一,学习、实现、对比各种排序算法,掌握各种排序算法的优劣,以及各种算法使用的情况。
实验内容:使用简单数组实现下面各种排序算法,并进行比较。
排序算法:1、插入排序2、希尔排序3、冒泡排序4、快速排序5、简单选择排序6、堆排序7、归并排序8、基数排序(选作)9、其他要求:1、测试数据分成三类:正序、逆序、随机数据2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。
3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)4、对2和3的结果进行分析,验证上述各种算法的时间复杂度编写测试main()函数测试线性表的正确性。
2. 程序分析2.1 存储结构使用最简单的一维数组存储待排序的数据。
共使用两个数组,一个用来存储原始数据,一个用来存储待排序数据。
每次排序完毕,用原始数据更新一次待排序数据,保证每一次都对同一组数据排序。
(图略)2.2 关键算法分析1.直接插入的改进:在一般的直接插入中,关键码每移动一次就需要比较一次。
在移动的方面,优化是比较困难的,因为对静态线性表的插入必然要带来大量的移动。
但是,我们可以在比较上进行一些优化。
在查找技术一张曾学过的“折半查找法”,在这里就可以照葫芦画瓢地运用。
一趟排序的伪代码如下:1.如果该元素大于处于其左侧相邻的元素则跳过该元素;2.low=0,high=i;3.循环直至low==high3.1 mid=(low+high)/2;3.2如果当前元素大于中值high=mid;3.3否则low=mid+1;4.当前元素赋值给临时变量;5.将有序区中处于low位置及其右侧的元素右移;6.临时变量置于low位置简单说一下这里的折半查找与一般查找算法的区别。
这里的查找,尤其是对无重复数据和大量数据的处理中,更多的时候是找不到完全相等的项的。
北邮数据结构实验四-排序

2008级数据结构实验报告实验名称:实验四排序学生姓名:班级:班内序号:学号:日期:实验要求a. 实验目的通过实现下述实验内容,学习、实现、对比各种排序算法,掌握各种排序算法的优劣,以及各种算法使用的情况。
b. 实验内容2 题目2使用链表实现下面各种排序算法,并进行比较。
排序算法:1、插入排序2、冒泡排序3、快速排序4、简单选择排序5、其他要求:1、测试数据分成三类:正序、逆序、随机数据2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。
3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)4、对2和3的结果进行分析,验证上述各种算法的时间复杂度编写测试main()函数测试线性表的正确性2.程序分析:1.存储结构:单链表结点结构体为: struct Node{ int data ; Node * next } 2. 核心算法思想:1. 利用教材讲述的基本算法思想,实现四种排序算法,统计其运行相关数据。
2. 将四种排序函数入口地址作为函数头指针,实现快速调用和统计。
使得程序代码可读性增、结构更加优化。
3. 关键算法的实现: 关键算法1:实现四种算法的基本排序功能。
1、插入排序:依次将待排序的序列中的每一个记录插入到先前排序好的序列中,直到全部记录排头结点,排序完毕。
具体实现为:每次将s 赋值为头结点,而p 最初赋值为第一个含有data 的指针。
每次比较p 和s 的后继的数据大小,若是p 的数据小于s 的数据则将p 的后继结点插入到s 结点的后面同时s 返回到头结点重新比较插入,直至p 到达链表的尾部。
void LinkSort::InsertSort()//插入排序{Node * P = front->next; //要插入的节点的前驱while(P->next){Node * S = front; //用来比较的节点的前驱while(1){ CompareCount++;if( P->next->data < S->next->data ) // P后继比S后继小则把p的后继结点插入到s后继结点的后面,同时跳出这一层循环,将s重新赋值为front结点指针。
《数据结构》实验报告——排序

《数据结构》实验报告排序实验题目:输入十个数,从插入排序,快速排序,选择排序三类算法中各选一种编程实现。
实验所使用的数据结构内容及编程思路: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、掌握内排序的方法。
二、实验内容1、设计一个程序e xp10—1.cpp实现直接插入排序算法,并输出{9,8,7,6,5,4,3,2,1,0}的排序过程。
(1)源程序如下所示://文件名:exp10-1.cpp#include <stdio.h>#define MAXE 20//线性表中最多元素个数typedef int KeyType;typedef char InfoType[10];typedef struct //记录类型{KeyType key; //关键字项InfoType data; //其他数据项,类型为InfoType} RecType;void InsertSort(RecType R[],int n) //对R[0..n-1]按递增有序进行直接插入排序{int i,j,k;RecType temp;for (i=1;i<n;i++){temp=R[i];j=i-1; //从右向左在有序区R[0..i-1]中找R[i]的插入位置while (j>=0 && temp.key<R[j].key){R[j+1]=R[j];//将关键字大于R[i].key的记录后移j--;}R[j+1]=temp;//在j+1处插入R[i]printf("i=%d,",i);//输出每一趟的排序结果printf("插入%d,结果为: ",temp);for (k=0;k<n;k++)printf("%3d",R[k].key);printf("\n");}}void main(){int i,k,n=10;KeyType a[]={9,8,7,6,5,4,3,2,1,0};RecType R[MAXE];for (i=0;i<n;i++)R[i].key=a[i];printf("初始关键字: ");//输出初始关键字序列for (k=0;k<n;k++)printf("%3d",R[k].key);printf("\n");InsertSort(R,n);printf("最后结果: ");//输出初始关键字序列for (k=0;k<n;k++)printf("%3d",R[k].key);printf("\n");}(2)运行的结果如下图所示:2、设计一个程序exp10—2.cpp实现希尔插入排序算法,并输出{9,8,7,6,5,4,3,2,1,0}的排序过程。
北邮数据结构实验报告-排序

北邮数据结构实验报告-排序北邮数据结构实验报告-排序一、实验目的本实验旨在掌握常见的排序算法,包括冒泡排序、插入排序、选择排序、快速排序、归并排序等,并通过实际编程实现对数字序列的排序。
二、实验内容1.冒泡排序冒泡排序是一种简单的排序算法,其基本思想是依次比较相邻的两个元素,并按照从小到大或从大到小的顺序交换。
具体步骤如下:- 从待排序序列的第一个元素开始,依次比较相邻的两个元素;- 如果前面的元素大于后面的元素,则交换这两个元素的位置;- 重复上述步骤,直到整个序列有序。
2.插入排序插入排序是一种简单且直观的排序算法,其基本思想是将待排序序列分为已排序和未排序两部分,每次从未排序部分中选择一个元素插入到已排序部分的合适位置。
具体步骤如下:- 从待排序序列中选择一个元素作为已排序部分的第一个元素;- 依次将未排序部分的元素插入到已排序部分的合适位置,使得已排序部分保持有序;- 重复上述步骤,直到整个序列有序。
3.选择排序选择排序是一种简单且直观的排序算法,其基本思想是每次选择未排序部分中的最小(或最大)元素,并将其放在已排序部分的末尾。
具体步骤如下:- 在未排序部分中选择最小(或最大)的元素;- 将选择的最小(或最大)元素与未排序部分的第一个元素交换位置;- 重复上述步骤,直到整个序列有序。
4.快速排序快速排序是一种高效的排序算法,其基本思想是通过一趟排序将待排序序列分割成两部分,其中一部分的元素都比另一部分的元素小。
具体步骤如下:- 选择一个枢轴元素(一般选择第一个元素);- 将待排序序列中小于枢轴元素的元素放在枢轴元素的左侧,大于枢轴元素的元素放在枢轴元素的右侧;- 对枢轴元素左右两侧的子序列分别进行递归快速排序;- 重复上述步骤,直到整个序列有序。
5.归并排序归并排序是一种高效的排序算法,其基本思想是将待排序序列划分成足够小的子序列,然后对这些子序列进行两两合并,最终形成有序的序列。
具体步骤如下:- 将待排序序列递归地划分成足够小的子序列;- 对每个子序列进行归并排序;- 合并相邻的子序列,直到整个序列有序。
北邮数据结构实验四链表排序

数据结构实验报告实验名称:学生姓名:班级:班内序号:学号:日期:实验描述:使用链表实现下面各种排序算法,并进行比较。
排序算法:1、插入排序2、冒泡排序3、快速排序4、简单选择排序5、其他一.程序分析1.存储结构:双向链表2.关键算法分析:a)插入排序:⒈从有序数列和无序数列{a2,a3,…,an}开始进行排序;⒉处理第i个元素时(i=2,3,…,n),数列{a1,a2,…,ai-1}是已有序的,而数列{ai,ai+1,…,an}是无序的。
用ai与ai-1,a i-2,…,a1进行比较,找出合适的位置将ai插入;⒊重复第二步,共进行n-i次插入处理,数列全部有序。
b)冒泡排序:1.比较相邻的元素。
如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。
在这一点,最后的元素应该会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
c)快速排序:一趟快速排序的算法是:1.设置两个变量i、j,排序开始的时候:i=0,j=N-1;2.以第一个数组元素作为关键数据,赋值给key,即key=A[0];3.从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换;4.从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;5.重复第3、4步,直到i=j;(3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。
找到符合条件的值,进行交换的时候i,j指针位置不变。
另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。
d)简单选择排序:设所排序序列的记录个数为n。
i取1,2,…,n-1,从所有n-i+1个记录(Ri,Ri+1,…,Rn)中找出排序码最小的记录,与第i个记录交换。
北邮数据结构实验报告

北邮数据结构实验报告北邮数据结构实验报告一、引言数据结构是计算机科学中的重要基础知识,对于计算机程序的设计和性能优化起着至关重要的作用。
本报告旨在总结北邮数据结构实验的相关内容,包括实验目的、实验设计、实验过程和实验结果等。
二、实验目的本次实验旨在通过实践操作,加深对数据结构的理解和应用能力。
具体目的如下:1. 掌握线性表、栈和队列等基本数据结构的实现方法;2. 熟悉二叉树、图等非线性数据结构的构建和遍历算法;3. 学会使用递归和非递归算法解决实际问题;4. 培养编程实践能力和团队合作意识。
三、实验设计本次实验包括以下几个部分:1. 线性表实验:设计一个线性表类,实现线性表的基本操作,如插入、删除和查找等。
通过实验,了解线性表的顺序存储和链式存储结构的特点和应用场景。
2. 栈和队列实验:设计栈和队列类,实现栈和队列的基本操作,如入栈、出栈、入队和出队等。
通过实验,掌握栈和队列的应用,如括号匹配、迷宫求解等。
3. 二叉树实验:设计二叉树类,实现二叉树的创建、遍历和查找等操作。
通过实验,熟悉二叉树的前序、中序和后序遍历算法,并了解二叉树的应用,如表达式求值等。
4. 图实验:设计图类,实现图的创建、遍历和最短路径等操作。
通过实验,掌握图的邻接矩阵和邻接表表示方法,并了解图的深度优先搜索和广度优先搜索算法。
四、实验过程1. 线性表实验:根据实验要求,首先选择线性表的存储结构,然后设计线性表类,实现插入、删除和查找等基本操作。
在实验过程中,遇到了一些问题,如边界条件的处理和内存管理等,通过团队合作,最终解决了这些问题。
2. 栈和队列实验:根据实验要求,设计栈和队列类,实现入栈、出栈、入队和出队等基本操作。
在实验过程中,我们发现了栈和队列在实际应用中的重要性,如括号匹配和迷宫求解等,通过实验加深了对栈和队列的理解。
3. 二叉树实验:根据实验要求,设计二叉树类,实现二叉树的创建、遍历和查找等操作。
在实验过程中,我们发现了二叉树在表达式求值和排序等方面的应用,通过实验加深了对二叉树的理解。
数据结构实验报告-实验5-排序

数据结构实验报告实验名称:排序学号:姓名:实验日期:2016.07.01一、实验目的至少掌握一种排序算法二、实验内容随机生成10个从1-100之间的随机数,编程实现至少一种排序算法,对该数据进行排序。
要求1、要排序的数据随机生成2、先升序排序一次,再用同样的算法降序排序一次(2)分析(3)实验代码#include <stdio.h>#include <stdlib.h>#include <time.h>typedef struct{int key;}keytype;typedef struct{ keytype r[1000];int length;}sqlist;/*产生随机数*/void creat(sqlist *l){int i;printf("请输入要产生的随机数个数:");scanf("%d",&l->length);srand((unsigned)time(NULL));for(i=1;i<=l->length;i++){l->r[i].key = rand() %900+100;printf("%d ",l->r[i].key);}printf("\n");}/*交换顺序表中子表r[low...high]的记录,使枢轴记录到位,并返回其所在的位置*/int partion(sqlist *l,int low,int high){ int pivotkey;l->r[0]=l->r[low];pivotkey=l->r[low].key;while(low<high){ while(low<high&&l->r[high].key>=pivotkey) --high;l->r[low]=l->r[high];while(low<high&&l->r[low].key<=pivotkey) ++low;l->r[high]=l->r[low];}l->r[low]=l->r[0];return low;}/*快速排序*/void Qsort(sqlist *l,int low,int high){ int pivotloc;if(low<high){ pivotloc=partion(l,low,high);Qsort(l,low,pivotloc-1);Qsort(l,pivotloc+1,high);}}/*显示顺序表*/void display(sqlist *l){ int i;for(i=1;i<=l->length;i++)printf("%-4.2d",i);printf("\n");for(i=1;i<=2*l->length;i++)printf("--");printf("\n");for(i=1;i<=l->length;i++)printf("%-4.2d",l->r[i].key);}/*主函数*/void main(){sqlist t;creat(&t);Qsort(&t,1,t.length);printf("\n\n");printf("快速排序:\n");display(&t);}三、实验小结。
数据结构实验报告排序

数据结构实验报告排序数据结构实验报告:排序引言:排序是计算机科学中常见的算法问题之一,它的目标是将一组无序的数据按照特定的规则进行排列,以便于后续的查找、统计和分析。
在本次实验中,我们将学习和实现几种常见的排序算法,并对它们的性能进行比较和分析。
一、冒泡排序冒泡排序是最简单的排序算法之一,它通过不断交换相邻的元素,将较大(或较小)的元素逐渐“冒泡”到数组的一端。
具体实现时,我们可以使用两层循环来比较和交换元素,直到整个数组有序。
二、插入排序插入排序的思想是将数组分为两个部分:已排序部分和未排序部分。
每次从未排序部分中取出一个元素,插入到已排序部分的适当位置,以保持已排序部分的有序性。
插入排序的实现可以使用一层循环和适当的元素交换。
三、选择排序选择排序每次从未排序部分中选择最小(或最大)的元素,与未排序部分的第一个元素进行交换。
通过不断选择最小(或最大)的元素,将其放置到已排序部分的末尾,从而逐渐形成有序序列。
四、快速排序快速排序是一种分治的排序算法,它通过选择一个基准元素,将数组划分为两个子数组,其中一个子数组的所有元素都小于等于基准元素,另一个子数组的所有元素都大于基准元素。
然后对两个子数组分别递归地进行快速排序,最终将整个数组排序。
五、归并排序归并排序也是一种分治的排序算法,它将数组划分为多个子数组,对每个子数组进行排序,然后再将排好序的子数组合并成一个有序的数组。
归并排序的实现可以使用递归或迭代的方式。
六、性能比较与分析在本次实验中,我们对以上几种排序算法进行了实现,并通过对不同规模的随机数组进行排序,比较了它们的性能。
我们使用了计算排序时间的方式,并记录了每种算法在不同规模下的运行时间。
通过对比实验结果,我们可以得出以下结论:1. 冒泡排序和插入排序在处理小规模数据时表现较好,但在处理大规模数据时性能较差,因为它们的时间复杂度为O(n^2)。
2. 选择排序的时间复杂度也为O(n^2),与冒泡排序和插入排序相似,但相对而言,选择排序的性能稍好一些。
《数据结构》 实验报告4

xxx实验报告课程名称数据结构实验名称实验四排序操作系部班级姓名学号实验时间2012 年12月10日时分~时分地点机位评语指导教师:成绩一、实验目的1. 掌握常用的排序方法,并掌握用高级语言实现排序算法的方法;2. 深刻理解排序的定义和各种排序方法的特点,并能加以灵活应用;3. 了解各种方法的排序过程及其时间复杂度的分析方法。
二、实验内容统计成绩:给出n个学生的考试成绩表,每条信息由姓名和分数组成,试设计一个算法:(1)按分数高低次序,打印出每个学生在考试中获得的名次,分数相同的为同一名次;(2)按名次列出每个学生的姓名与分数。
三、实验步骤1. 定义结构体。
2. 定义结构体数组。
3. 定出主程序,对数据进行排序。
四、程序主要语句及作用1. 程序原代码如下:#include <string.h>#include "stdio.h"#include <malloc.h>#include <conio.h>typedef struct BSTNODE{int data;struct BSTNODE *lchild;struct BSTNODE *rchild;}BSTNODE;BSTNODE* initBST(int n, BSTNODE *p){if(p==NULL){p=(BSTNODE*)malloc(sizeof(BSTNODE));p->lchild=NULL;p->rchild=NULL;p->data=n;}else if(n>p->data)p->rchild=initBST(n,p->rchild);elsep->lchild=initBST(n,p->lchild);return p;}void inorder(BSTNODE *BT){if(BT!=NULL){inorder(BT->lchild);printf("%d ",BT->data);inorder(BT->rchild);}}BSTNODE *search_btree(BSTNODE *root,int key) { if (!root){printf("Emptu btree\n"); return root; }while(root->data!=key){ if(key<root->data)root=root->lchild;elseroot=root->rchild;if(root==0){ printf("Search Failure\n");break ;}} /* while(root->info!=key) */if (root !=0)printf("Successful search\n key=%d\n",root->data);return root ;} /* *search_btree(root,key) */int main(){BSTNODE *p=NULL;int i,n,sd;int a[100];printf("enter the number of nodes:");scanf("%d",&n);printf("enter the number of the tree:");for(i=0;i<n;i++){scanf("%d",&a[i]);p=initBST(a[i],p);}inorder(p);printf("\n please input search data:");scanf("%d",&sd);search_btree(p,sd);getch();return 1;}2. 运行结果截图:五、总结体会本次试验让我学习到了很多也认识到了自己的不足:1.大部分的时间都用在了编程上,主要是因为C语言掌握的问题,C语言基础不好特别是对于C语言中链表的一些定义和基本操作不够熟练,导致在编程过程中还要不断的拿着c语言的教材查找,所以今后还要对C语言多练习,多动手,多思考。
排序的实验报告代码

一、实验目的1. 理解并掌握常见的排序算法原理。
2. 比较不同排序算法的时间复杂度和空间复杂度。
3. 分析不同数据规模下排序算法的性能差异。
二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.83. 排序算法:冒泡排序、选择排序、插入排序、快速排序、归并排序三、实验步骤1. 定义排序算法函数。
2. 生成不同规模的数据集。
3. 对数据集进行排序,记录排序时间。
4. 分析并比较不同排序算法的性能。
四、实验代码```pythonimport timeimport random# 冒泡排序def 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] # 选择排序def 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] # 插入排序def 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] = key# 快速排序def quick_sort(arr):if len(arr) <= 1:return arrpivot = arr[len(arr) // 2]left = [x for x in arr if x < pivot]middle = [x for x in arr if x == pivot]right = [x for x in arr if x > pivot]return quick_sort(left) + middle + quick_sort(right) # 归并排序def merge_sort(arr):if len(arr) <= 1:return arrmid = len(arr) // 2left = merge_sort(arr[:mid])right = merge_sort(arr[mid:])return merge(left, right)def merge(left, right):result = []i = j = 0while i < len(left) and j < len(right):if left[i] < right[j]:result.append(left[i])i += 1else:result.append(right[j])j += 1result.extend(left[i:])result.extend(right[j:])return result# 生成随机数据集def generate_data(n):return [random.randint(1, 1000) for _ in range(n)] # 比较排序算法性能def compare_sorts(n):data = generate_data(n)algorithms = {"冒泡排序": bubble_sort,"选择排序": selection_sort,"插入排序": insertion_sort,"快速排序": quick_sort,"归并排序": merge_sort}for name, algorithm in algorithms.items():start_time = time.time()algorithm(data.copy())elapsed_time = time.time() - start_timeprint(f"{name} - 时间:{elapsed_time:.6f}秒") # 执行实验if __name__ == "__main__":for n in [1000, 5000, 10000]:print(f"数据规模:{n}")compare_sorts(n)```五、实验结果与分析1. 当数据规模为1000时,快速排序和归并排序的时间复杂度较高,但相较于其他排序算法,性能表现较好。
北邮数据结构 实验报告四——哈夫曼树

数据结构实验报告实验名称:实验4——题目4——哈夫曼树学生姓名:班级:班内序号:学号:日期:2017年1月6日1.实验要求利用二叉树结构实现哈夫曼编/解码器。
基本要求:1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并建立赫夫曼树2、建立编码表(CreateTable):利用已经建好的赫夫曼树进行编码,并将每个字符的编码输出。
3、编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的字符串输出。
4、译码(Decoding):利用已经建好的赫夫曼树对编码后的字符串进行译码,并输出译码结果。
5、打印(Print):以直观的方式打印赫夫曼树(选作)6、计算输入的字符串编码前和编码后的长度,并进行分析,讨论赫夫曼编码的压缩效果。
2. 程序分析2.1 存储结构本实验的存储结构为哈夫曼树与哈夫曼编码表哈夫曼树:存储结构:struct HNode//哈夫曼树的结点结构{int weight;//结点权值int parent;//双亲指针int LChild;//左孩子指针int RChild;//右孩子指针};哈夫曼编码表:struct HCode//编码表的结点结构{char data;//字符char code[10];//编码int k;//码长};存储结构:2.2 关键算法分析一、初始化:步骤:1、设立数组,记录每一个字符出现的次数与字符对应的ASCII码2、以字符不是回车或换行遍历输入的字符数组3、将存储出现次数大于0的字符存储进叶子节点数组4、相对应的,存储叶子结点的数据域字符出现的次数。
时间复杂度:O(n)空间复杂度:O(n)二、创建哈夫曼树步骤:1、创建2n-1个数节点2、将权值数组依次赋值进0到n-1的权值节点中3、从0到i-1(最开始等于n-1)选择两个权值最小的节点x、y,将其连接为i节点的左右孩子,改变x、y的双亲指针为i节点4、I++,循环步骤4直到2n-1时间复杂度:O(n^2)空间复杂度 O(n)三、创建哈夫曼编码表步骤:1、创建n个编码表节点2、依次将叶子节点的字符放入编码表节点数据域中3、对每个编码表对应的树结点,向根节点开始回溯(为父节点的左孩子编码值为0,右孩子为1,不断上移,直到根节点)4、进行倒置时间复杂度O(n)空间复杂度 O(n)四、编码步骤:1、新建编码数组2、从源码第一个字符开始在编码表中寻找到相应字符后将编码复制进编码数组3、计算压缩比时间复杂度O(n+e) n为源码 e为编码数组长度空间复杂度O(n)五、解码步骤:1、从根节点开始,按照编码串寻找(0为左子树,1为右子树)2、直到该节点无子树,将该节点(也就是叶子节点)字符放入解码串中3、重复步骤1、2直到编码串结束时间复杂度O(n) n为编码串长度空间复杂度O(e) e为原串长度六、打印哈夫曼树步骤:1、从根节点开始第m层前方空m个格2、叶子结点先输出数据域再在下一行输出权值3、重复输出,递归调用,直到叶子。
最新实验四排序实验报告

最新实验四排序实验报告实验目的: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秒。
实验结论:通过实验,我们发现快速排序在大多数情况下都比其他三种简单排序算法有更高的效率。
冒泡排序、选择排序和插入排序在最坏情况下的时间复杂度都较高,适合处理小规模数据集或者基本有序的数据。
数据结构课程设计报告---几种排序算法的演示(附源代第四次实验码)

本周的实验主要做快速排序,自己随机生成10000个数据,用快速排序算法,输出排序完成所需时间,再用其他排序方法做比较,至少完成两个算法的效率比较数据结构课程设计报告—几种排序算法的演示时间:2010-1-14一需求分析运行环境Microsoft Visual Studio 2005程序所实现的功能对直接插入排序、折半插入排序、冒泡排序、简单选择排序、快速排序、堆排序、归并排序算法的演示,并且输出每一趟的排序情况。
程序的输入(包含输入的数据格式和说明)<1>排序种类三输入<2>排序数的个数的输入<3>所需排序的所有数的输入程序的输出(程序输出的形式)<1>主菜单的输出<2>每一趟排序的输出,即排序过程的输出二设计说明算法设计思想<1>交换排序(冒泡排序、快速排序)交换排序的基本思想是:对排序表中的数据元素按关键字进行两两比较,如果发生逆序(即排列顺序与排序后的次序正好相反),则两者交换位置,直到所有数据元素都排好序为止。
<2>插入排序(直接插入排序、折半插入排序)插入排序的基本思想是:每一次设法把一个数据元素插入到已经排序的部分序列的合适位置,使得插入后的序列仍然是有序的。
开始时建立一个初始的有序序列,它只包含一个数据元素。
然后,从这个初始序列出发不断插入数据元素,直到最后一个数据元素插到有序序列后,整个排序工作就完成了。
<3>选择排序(简单选择排序、堆排序)选择排序的基本思想是:第一趟在有n个数据元素的排序表中选出关键字最小的数据元素,然后在剩下的n-1个数据元素中再选出关键字最小(整个数据表中次小)的数据元素,依次重复,每一趟(例如第i趟,i=1,…,n-1)总是在当前剩下的n-i+1个待排序数据元素中选出关键字最小的数据元素,作为有序数据元素序列的第i个数据元素。
等到第n-1趟选择结束,待排序数据元素仅剩下一个时就不用再选了,按选出的先后次序所得到的数据元素序列即为有序序列,排序即告完成。
北邮数据结构实验报告 实验四 排序

数据结构实验报告实验名称:实验四——排序学生姓名:1.实验要求实验目的:通过选择实验内容中的两个题目之一,学习、实现、对比、各种排序的算法,掌握各种排序算法的优劣,以及各种算法使用的情况。
题目2:使用简单数组实现下面各种排序算法,并进行比较。
排序算法如下:1、插入排序;2、希尔排序;3、冒泡排序;4、快速排序;5、简单选择排序;6、堆排序;7、归并排序;8、基数排序(选作);9、其他。
具体要求如下:1、测试数据分成三类:正序、逆序、随机数据。
2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换记为3次移动)。
3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微妙。
4、对2和3的结果进行分析,验证上述各种算法的时间复杂度。
5、编写main()函数测试各种排序算法的正确性。
2. 程序分析2.1 存储结构2.2 关键算法分析一、关键算法:1、插入排序a、取排序的第二个数据与前一个比较b、若比前一个小,则赋值给哨兵c、从后向前比较,将其插入在比其小的元素后d、循环排序2、希尔排序a、将数组分成两份b、将第一份数组的元素与哨兵比较c、若其大与哨兵,其值赋给哨兵d、哨兵与第二份数组元素比较,将较大的值赋给第二份数组e、循环进行数组拆分3、对数据进行编码a、取数组元素与下一个元素比较b、若比下一个元素大,则与其交换c、后移,重复d、改变总元素值,并重复上述代码4、快速排序a、选取标准值b、比较高低指针指向元素,若指针保持前后顺序,且后指针元素大于标准值,后指针前移,重新比较c、否则后面元素赋给前面元素d、若后指针元素小于标准值,前指针后移,重新比较e、否则前面元素赋给后面元素5、简单选择排序a、从数组中选择出最小元素b、若不为当前元素,则交换c、后移将当前元素设为下一个元素6、堆排序a、生成小顶堆b、将堆的根节点移至数组的最后c、去掉已做过根节点的元素继续生成小顶堆d、数组倒置7、归并排序a、将数组每次以1/2拆分,直到为最小单位b、小相邻单位数组比较重排合成新的单位c、循环直至完成排序二、代码详细分析:1、插入排序关键代码:①取排序的第二个数据与前一个比较:if(r[i]<r[i-1])②若比前一个小,则赋值给哨兵:r[0]=r[i];③从后向前比较,将其插入在比其小的元素后:for(j=i-1;r[0]<r[j];j--){r[j+1]=r[j];a++;} r[j+1]=r[0];④循环排序2、希尔排序关键代码:①将数组分成两份:d=n/2②将第一份数组的元素与哨兵比较:for(int i=d+1;i<=n;i++)③若其大与哨兵,其值赋给哨兵:if(r[0]<r[i-d]){ r[0]=r[i];}④哨兵与第二份数组元素比较,将较大的值赋给第二份数组:for(j=i-d;j>0&&r[0]<r[j];j=j-d) {r[j+d]=r[j]; }⑤循环进行数组拆分:for(int;d>=1;d=d/2)3、冒泡排序关键代码:①取数组元素与下一个元素比较: for(int i=1;i<bound;i++)if(r[i]>r[i+1])②若比下一个元素大,则与其交换: r[0]=r[i]; r[i]=r[i+1]; r[i+1]=r[0];③后移,重复:for(int i=1;i<bound;i++)④改变总元素值,并重复上述代码:int bound=pos;4、快速排序关键代码:①选取标准值:r[0]=r[i]②比较高低指针指向元素,若指针保持前后顺序,且后指针元素大于标准值,后指针前移,重新比较:while(i<j&&r[j]>=flag) {j--;}③否则后面元素赋给前面元素:r[i]=r[j];④若后指针元素小于标准值,前指针后移,重新比较:while(i<j&&r[i]<=flag){i++;}⑤否则前面元素赋给后面元素:r[j]=r[i];5、简单选择排序关键代码:①从数组中选择出最小元素: for(int j=i+1;j<=n;j++)②{if(r[j]<r[index]) index=j; }③若不为当前元素,则交换:if(index!=i) {r[0]=r[i]; r[i]=r[index];r[index]=r[0];}④后移将当前元素设为下一个元素:for(int i=1;i<n;i++)6、堆排序关键代码:①生成小顶堆:while(j<=m) {if(j<m&&r[j]>r[j+1]) {j++;}②if(r[i]<r[j]) {break; }③else{ int x; x=r[i]; r[i]=r[j]; r[j]=x; i=j; j=2*i; }}④将堆的根节点移至数组的最后: x=r[1]; r[1]=r[n-i+1]; r[n-i+1]=x;⑤去掉已做过根节点的元素继续生成小顶堆:sift(r,1,n-i,x,y);⑥数组倒置输出: for(int i=n;i>0;i--)cout<<r[i]<<" ";7、归并排序关键代码:①将数组每次以1/2拆分,直到为最小单位:mid=(low+high)/2;②小相邻单位数组比较重排合成新的单位:while(i<=m&&j<=high)if(L.r[i]<=L.r[j]) t[k++]=L.r[i++];else t[k++]=L.r[j++];while(i<=m) t[k++]=L.r[i++];while(j<=high) t[k++]=L.r[j++];for(i=low,k=0;i<=high;i++,k++) L.r[i]=t[k];三、计算关键算法的时间、空间复杂度插入排序O(n2)希尔排序O(n2)冒泡排序O(n2)快速排序O(nlog2n)简单选择排序O(n2)堆排序O(nlog2n)归并排序O(nlog2n)3. 程序运行结果1、测试主函数流程:流程图如图所示流程图示意图程序运行结果图如下:2、测试条件:按题目要求分别输入同组数据的正序、逆序、随机序列进行测试。
数据结构排序实验报告

数据结构排序实验报告一、实验目的本次数据结构排序实验的主要目的是深入理解和掌握常见的排序算法,包括冒泡排序、插入排序、选择排序、快速排序和归并排序,并通过实际编程和实验分析,比较它们在不同规模数据下的性能表现,从而为实际应用中选择合适的排序算法提供依据。
二、实验环境本次实验使用的编程语言为 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、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构实验报告实验名称:实验4——排序学生姓名:申宇飞班级:2012211103班内序号:03学号:2012210064日期:2013年12月18日1.实验要求使用简单数组实现下面各种排序算法,并进行比较。
排序算法:1、插入排序2、希尔排序3、冒泡排序4、快速排序5、简单选择排序6、堆排序(选作)7、归并排序(选作)8、基数排序(选作)9、其他要求:1、测试数据分成三类:正序、逆序、随机数据2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。
3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)4、对2和3的结果进行分析,验证上述各种算法的时间复杂度编写测试main()函数测试线性表的正确性。
2. 程序分析(1)、设计一个菜单,格式如下:1、直接插入排序2、希尔排序3、冒泡排序4、快速排序5、选择排序6、堆排序7、退出(2)、选择不同的菜单但进行相应的排序,并给出排序的关键字序列。
2.1 存储结构2.2 关键算法分析本程序包含了9个函数,它们分别是:(1)、直接插入排序的算法函数InsertSort()。
void InsertSort(SqList &L){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];for( j=i-2; (L.r[0].key < L.r[j].key); j--) L.r[j+1] = L.r[j];L.r[j+1] = L.r[0];}}}(2)、希尔排序的算法函数ShellSort()。
void ShellSort(SqList &L){int i, j;int dk = 1;//增量while(dk <=L.length/3)dk = 3*dk+1;//增大增量while(dk>0){dk /= 3;//减小增量for (i = dk; i <=L.length; i++) {L.r[0].key = L.r[i].key;j = i;while ((j >= dk) && (L.r[j-dk].key > L.r[0].key)) { L.r[j].key = L.r[j-dk].key;j -= dk;}L.r[j].key = L.r[0].key;}}}(3)、冒泡排序算法函数BubbleSort()。
void BubbleSort(SqList &L){int i,j;for(i=0;i<L.length-2;i++){int flag = 1;for(j=0;j<L.length-i-2;j++)if(L.r[j].key > L.r[j+1].key){flag = 0;int temp;temp = L.r[j].key;L.r[j].key = L.r[j+1].key;L.r[j+1].key = temp;}//若无交换说明已经有序if(flag==1)break;} }(4)、快速排序的算法函数Partition()。
void BubbleSort(SqList &L){int i,j;for(i=0;i<L.length-2;i++){int flag = 1;for(j=0;j<L.length-i-2;j++)if(L.r[j].key > L.r[j+1].key){flag = 0;int temp;temp = L.r[j].key;L.r[j].key = L.r[j+1].key;L.r[j+1].key = temp;}//若无交换说明已经有序if(flag==1)break;} }(5)、选择排序算法函数SelectSort()。
void SelectSort(SqList &L){int min;int j;for (int i = 0; i <L.length; i++){ // 选择第i小的记录,并交换j = i;min = L.r[i].key;for (int k = i; k < L.length; k++){ // 在R[i..n-1]中选择最小的记录if (L.r[k].key < min){min = L.r[k].key ;j = k;}}if (i != j){ // 与第i个记录交换int temp = L.r[i].key;L.r[i].key = L.r[j].key;L.r[j].key = temp;}}}(6)、堆排序算法函数HeapAdjust()。
void HeapAdjust(HeapType &H,int s,int m) 第6/10页//堆调整,将记录调整为小顶堆int j; RedType rc = H.r[s];//暂时存储根结点for(j=2*s; j<=m; j*=2){//沿着结点记录较小的向下筛选if(j<m && H.r[j].key<H.r[j+1].key)++j;if(rc.key>= H.r[j].key)break;H.r[s] = H.r[j];s = j;}H.r[s] = rc;}void HeapSort(HeapType &H){int i;RedType temp;for(i = H.length; i>0; --i)HeapAdjust(H,i,H.length);for(i=H.length; i>1; --i){temp = H.r[1];H.r[1] = H.r[i];H.r[i] = temp;HeapAdjust(H,1,i-1);}(7)、对存储数字的遍历函数Visit()、初始化函数InitSqList()。
void Visit(SqList L){for(int i=1; i<=L.length; i++)cout<<L.r[i].key<<" ";cout<<endl;}void InitSqList(SqList &L,int a[]){for(int i=1;i<=L.length;i++)L.r[i].key = a[i];}(8)、主函数main()。
关键算法的时间、空间复杂度:排序法平均时间最差情形稳定度额外空间备注冒泡 O(n2) O(n2) 稳定 O(1) n小时较好交换 O(n2) O(n2) 不稳定 O(1) n小时较好选择 O(n2) O(n2) 不稳定 O(1) n小时较好插入 O(n2) O(n2) 稳定 O(1) 大部分已排序时较好Shell O(nlogn) O(n s) 1<s<2 不稳定 O(1) s是所选分组快速 O(nlogn) O(n2) 不稳定 O(nlogn) n大时较好归并 O(nlogn) O(nlogn) 稳定 O(1) n大时较好堆 O(nlogn) O(nlogn) 不稳定 O(1) n大时较好2.3 其他3. 程序运行结果主函数流程:4. 总结首先,对程序的设计缺少优化,本次程序需要运行之后手动进行输入数据,以后可以尝试把数据改为在源代码中输入,这样就可以运行之后马上显示数据,这样就避免了相同数据的重复输入。
此外,生成数组函数及本程序中的代码有的采用了递归形式,如果考虑用栈来模拟的话,效率会有提升,所以运行时间还和代码的实现有关。
本程序出现过的问题是主函数对个函数的调用以及对存储数组的调用上出现了问题,导致排序的结果以及排序的界面出现了问题,得不到实现。
后来对算法进行改进,最终把问题得以解决。
而且以后可以试着去写一段可以计算出时间的函数。
代码#include<iostream>#include <time.h>#include <windows.h>using namespace std;int i,j,temp,k;//设置全局变量long double GetNowTime() //取系统时间{LARGE_INTEGER litmp;LONG64 QPart;QueryPerformanceCounter(&litmp);QPart=litmp.QuadPart;return (long double)QPart;}//插入排序void InsertSort(int r[], int n){ int move=0, compare=0;long double start=0,end=0,time=0;start=GetNowTime();for(i=2;i<n;i++){if(r[i]<r[i-1]) //记录后项小于记录前项时进行排序{ compare++;r[0]=r[i]; //设置哨兵,存放待排序记录值for(j=i-1;r[0]<r[j];j--,compare++) //寻找插入位置r[j+1]=r[j]; //比r[0]大的往后移r[j+1]=r[0]; //插入指定记录值move=move+3; //关键码的交换按3次记compare++;}}end=GetNowTime();time=end-start;for(k=1;k<n;k++)cout<<r[k]<<" "; //输出排序后记录cout<<endl;cout<<"排序所需时间:"<<time<<"us 移动次数:"<<move<<" 比较次数:"<<compare;cout<<endl<<endl;}//希尔排序void ShellSort(int r[], int n){int move=0,compare=0;long double start=0,end=0,time=0;start=start=GetNowTime();int d; //定义增量for(d=n/2;d>=1;d=d/2) //以增量为d进行直接插入排序{for(i=d+1;i<n;i++){compare++;r[0]=r[i]; //设置哨兵,暂存被插入记录for(j=i-d;j>0&&r[0]<r[j];j=j-d,compare++)r[j+d]=r[j]; //记录后移d个位置r[j+d]=r[0]; //插入指定记录值move=move+3;compare++;}}end=GetNowTime();time=end-start;for(i=1;i<n;i++)cout<<r[i]<<" "; //输出排序后记录cout<<endl;cout<<"排序所需时间:"<<time<<"us 移动次数:"<<move<<" 比较次数:"<<compare;cout<<endl<<endl;}//改进型起泡排序void BubbleSort(int r[], int n){long double start=0,end=0,time=0;int move=0,compare=0;int exchange;int bound;exchange=n-1; //第一趟起泡排序的范围是r[0]到r[n-1]start=GetNowTime();while (exchange) //仅当上一趟排序有记录交换才进行本趟排序{bound=exchange; //表示无序的范围exchange=0;for(int j=0;j<bound;j++,compare++) //一趟起泡排序if (r[j]>r[j+1]){temp=r[j]; //交换r[i]和r[i+1]r[j]=r[j+1];r[j+1]=temp;move=move+3;exchange=j; //记录每一次发生记录交换的位置,即记录无序区的位置}compare++;}end=GetNowTime();time=end-start;for(int i=0;i<n;i++)cout<<r[i]<<" "; //输出排序后记录cout<<endl;cout<<"排序所需时间:"<<time<<" us 移动次数:"<<move<<" 比较次数:"<<compare;cout<<endl<<endl;}//快速排序一次划分int Emove=0,Ecompare=0;long double Etime;int Partition(int r[], int first, int end){i=first; //初始化j=end;while (i<j) //循环的停止条件是i=j{while(i<j&&r[i]<=r[j]){ Ecompare++;j--; } //右侧扫描Ecompare++;if(i<j){temp=r[i]; //将较小记录交换到前面r[i]=r[j];r[j]=temp;Emove=Emove+3;/*i++; */}while(i<j&&r[i]<=r[j]){ Ecompare++; i++; } //左侧扫描,小于轴值的不移动,找到大于轴值的Ecompare++;if(i<j){temp=r[j];r[j]=r[i];r[i]=temp; //将较大记录交换到后面Emove=Emove+3;/* j--;*/}}return i; //i为轴值记录的最终位置}//快速排序,在一次排序结束后,左边区的元素都比右边区的小,只要分开再排序即可void QuickSort(int r[],int first,int end2){long double start=0,end=0;start=GetNowTime();if (first<end2){ //递归结束int pivot=Partition(r,first,end2); //一次划分QuickSort(r,first,pivot-1); //递归地对左侧子序列进行快速排序QuickSort(r,pivot+1,end2); //递归地对右侧子序列进行快速排序}end=GetNowTime();Etime=end-start;}void Print(){cout<<endl<<"排序所需时间:"<<Etime<<"us;移动的次数:"<<Emove<<";比较的次数:"<<Ecompare<<endl<<endl;}//简单选择排序,每一趟都找到最小值与比较域内第一个值交换void SelectSort(int r[], int n){long double start=0,end=0,time=0;int compare=0,move=0;int index; //设置关键值下标start=GetNowTime();for(i=0;i<n-1;i++) //对n个记录进行n-1趟简单选择排序{index=i;for(j=i+1;j<n;j++,compare++) //在无序区中选取最小记录if(r[j]<r[index]) //有记录小于关键值记录index=j; //更新关键值记录if(index!=i) //若第一个是最小值就不用交换{temp=r[i];r[i]=r[index];r[index]=temp; //交换r[i]和关键值记录move=move+3;}compare++;}end=GetNowTime();time=end-start;for(i=0;i<n;i++)cout<<r[i]<<" "; //输出排序后记录cout<<endl<<"排序所需时间:"<<time<<"us 移动次数:"<<move<<" 比较次数:"<<compare;cout<<endl<<endl;}//对数列进行排序void px(int r[],int numv){cout<<"\n直接顺序排序结果为: ";InsertSort(r,numv);cout<<"希尔排序结果为: ";ShellSort(r,numv);cout<<"起泡排序结果为: ";BubbleSort(r, numv-1);cout<<"快速排序结果为: ";QuickSort(r,0,numv-1);for(int i=0;i<numv-1;i++)cout<<r[i]<<" ";Print();Emove=0;Ecompare=0;cout<<"\n";cout<<"简单选择排序结果为: ";SelectSort(r,numv-1);}//主函数int main(){const int numv=11;int a[numv]={0};int b[numv]={0};int c[numv]={0}; //初始化cout<<"请输入10位正整数."<<endl;cout<<"第一组,正序输入a[]= ";try{for(i=1;i<numv;i++)cin>>a[i]; //从键盘输入待排序记录值}catch(char *wrong){cout<<wrong;}px(a,numv); //调用排序函数cout<<"\n第二组,反序输入b[]= ";try{for(i=1;i<numv;i++)cin>>b[i]; //从键盘输入待排序记录值}catch(char *wrong){cout<<wrong;}px(b,numv); //调用排序函数cout<<"\n第三组,随机输入c[]= ";try{for(i=1;i<numv;i++)cin>>c[i]; //从键盘输入待排序记录值}catch(char *wrong){cout<<wrong;}px(c,numv); //调用排序函数return 0;}。