数据结构第三次实验+第二题链表排序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构实验报告
实验名称:实验三——排序
学生姓名:XXX
班级:xxxxxxxxxxx
班内序号:
学号:
日期:2018年6月3日
1.实验要求
实验目的:通过选择下面两个题目之一,学习、实现、对比各种排序算法,掌握各种排序算法的优劣,以及各种算法使用的情况。
实验内容:使用链表实现下面各种排序算法,并进行比较。
排序算法:
1、插入排序
2、冒泡排序
3、快速排序
4、简单选择排序
5、其他
要求:
1、测试数据分成三类:正序、逆序、随机数据
2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其
中关键字交换计为3次移动)。
3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒
(选作)
4、对2和3的结果进行分析,验证上述各种算法的时间复杂度
编写测试main()函数测试线性表的正确性。
2. 程序分析
2.1 存储结构
单链表,储存每个元素值同时,储存该元素的直接后继元素位置信息。即数据域(data),指针域(next)。struct Node
{
int data;
struct Node *next;
};
2.2 关键算法分析
链表的建立:
Linklist::Linklist (int a[],int n)
{
front = new Node;
Node *r = front ;
for(int i=0;i { Node *s = new Node; s->data = a[i]; r->next = s; r=s; } r->next = NULL; } 尾插法创建链表:①堆中建立新节点②将a[i]写入新节点data域③新节点加入链表r->next=s. ④修改尾指针r=s. 简单选择排序: void Linklist ::Link_Selectsort (int n) { Node *p=front->next ; int a=0,b=0; //a记载比较次数,b记载移动次数 while(p!=NULL) { Node *s =p; //s指向最小节点 Node *q=p->next ; while(q!=NULL) { if(q->data a++; q=q->next ; } if(p!=s) { int t=p->data ;p->data =s->data ;s->data =t; //交换节点值 b=b+3; } p=p->next ; } Print(n,a,b); } 建立p节点记载有序区最后节点的下一个节点,s节点则记载无序区的最小节点,q节点用于遍历链表无序区,找出最小值。每次循环中q都找到无序最小节点,用s指向该节点,后 p和s节点值交换。 时间复杂度为O(n^2) 直接插入排序: void Linklist ::Link_Insertsort(int n) { Node *p=front; Node *q=front->next ; //q为无序区第一个节点的前驱 int a=0,b=0; //a记录比较次数,b记录移动次数 while(p->next !=NULL) { p=front; //初始化p为有序区的第一个前驱 while(q->next !=NULL&&p!=q) { a++; if (p->next ->data>q->next ->data ) //比较,交换节点顺序 { Node *s=q->next ; q->next =s->next ; //摘除s 节点 s->next =p->next ; //插到p 节点之后 p->next =s; b=b+3; break ; } p=p->next ; } if (p==q) q=q->next ; //若本躺排序无节点交换,则q 点下移 p=q; //当q 到链尾时,用于结束循环 } Print(n,a,b); } ① 指针p 指向有序区的待比较节点前驱(初始化时即front 节点)②指针q 指向无序区第 一个元素的前驱Ⅰ:若无序区的第一个节点值较大,则p 下移,直到p=q 为止Ⅱ:若无序区第一个元素节点值较小,则用指针s 指向该节点,然后摘除s 节点,插入到p 节点后继位置,即本趟循环结束。 时间复杂程度平均为O(n^2),最好为O(n),最坏为 O(n^2). …… …… ③ 冒泡排序: void Linklist ::Link_Bubblesort (int n) Node *p,*r; p=front->next ; r=NULL; //尾指针 int a=0,b=0; //a记载比较次数,b记载交换次数 while(p!=NULL&&r!=front->next ) { p=front->next ; //初始化p到链表头部 while(p->next !=r) { if(p->data >p->next ->data ) //相邻反序,则交换data域 { int t=p->data ; p->data =p->next ->data ; p->next ->data =t; b=b+3; } p=p->next ; a++; } r=p; //尾指针前移 } Print(n,a,b); } ①每趟排序,指针p指向无序区的待比较的节点,初始化时p指向无序区的第一个节点。②指针r指向有序区的第一个节点,初始化,r=NULL。③从p指针开始,前后两个节点的元素值比较,若反序则交换元素的data,否则p下移,直到计较到r为止,本趟排序完成。④一趟排序后,将尾指针前移一位,即r=p,直到r为第一个元素排序结束。 时间复杂程度平均为O(n^2),最好为O(n),最坏为O(n^2).