C++数据结构之链表排序.docx

上传人:b****4 文档编号:5650615 上传时间:2023-05-08 格式:DOCX 页数:14 大小:186.32KB
下载 相关 举报
C++数据结构之链表排序.docx_第1页
第1页 / 共14页
C++数据结构之链表排序.docx_第2页
第2页 / 共14页
C++数据结构之链表排序.docx_第3页
第3页 / 共14页
C++数据结构之链表排序.docx_第4页
第4页 / 共14页
C++数据结构之链表排序.docx_第5页
第5页 / 共14页
C++数据结构之链表排序.docx_第6页
第6页 / 共14页
C++数据结构之链表排序.docx_第7页
第7页 / 共14页
C++数据结构之链表排序.docx_第8页
第8页 / 共14页
C++数据结构之链表排序.docx_第9页
第9页 / 共14页
C++数据结构之链表排序.docx_第10页
第10页 / 共14页
C++数据结构之链表排序.docx_第11页
第11页 / 共14页
C++数据结构之链表排序.docx_第12页
第12页 / 共14页
C++数据结构之链表排序.docx_第13页
第13页 / 共14页
C++数据结构之链表排序.docx_第14页
第14页 / 共14页
亲,该文档总共14页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

C++数据结构之链表排序.docx

《C++数据结构之链表排序.docx》由会员分享,可在线阅读,更多相关《C++数据结构之链表排序.docx(14页珍藏版)》请在冰点文库上搜索。

C++数据结构之链表排序.docx

C++数据结构之链表排序

2009级数据结构实验报告

实验名称:

使用链表实现各种排序算法

学生姓名:

桂柯易

班级:

2009211120

班内序号:

07

学号:

09210580

日期:

2010年12月19日

1.实验要求

【实验目的】

通过选择实验内容中的两个题目之一,学习、实现、对比各种排序算法,掌握各种排序算法的优劣,以及各种算法的使用的情况。

【实验内容】

使用链表实现下面各种排序算法,并进行比较。

排序算法如下:

1插入排序;

2冒泡排序;

3快速排序;

4简单选择排序;

5其他。

具体要求如下。

1测试数据分成三类:

正序、逆序、随机数据。

2对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。

3对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)。

4对②和③的结果进行分析,验证上述各种算法的时间复杂度。

5编写main()函数测试各种排序算法的正确性。

2.程序分析

2.1存储结构

存储结构:

链表

2.2关键算法分析

【设计思想】

以直接插入排序为例:

首先将待排序数据建立一个带头结点的单链表。

在单链表中进行直接插入排序的基本思想是:

将单链表划分为有序区和无序区,有序区只包含一个元素节点,依次取无序区中的每一个结点,在有序区中查找待插入结点的插入位置,然后把该结点从单链表中删除,再插入到相应位置。

分析上述排序过程,需设一个工作指针q在无序区中指向待插入的结点,为了查找正确的插入位置,每趟排序前需将工作指针pre和p指向头结点和开始结点,在找到插入位置后,将结点q插在结点pre和p之间。

这相当于在单链表中删除结点q,因此为了保证链表不断开,须在删除结点q之前保留结点q的后继结点的地址。

【复杂度】

(1)建立链表存储数据的算法:

Node*CreateSortNode(intcount,int*array)

{

Node*p1,*p2,*head;

inti;

head=NULL;

for(i=0;i

{

p1=newNode;

p1->data=array[i];

p1->next=NULL;

if(i==0)

head=p1;

else

p2->next=p1;

p2=p1;

}

p2->next=NULL;

returnhead;

}

该算法的时间复杂度为T(N)=O(N)

(2)输出数据的算法:

voidListSortNode(Node*start)

{

Node*p;

p=start;

while(p!

=NULL)

{

cout<data<<'\0';

p=p->next;

}

cout<

}

该算法的时间复杂度T(N)=O(N)

(3)插入排序算法:

Node*Insert_Sort_LinkTable(Node*head)

{

_LARGE_INTEGERtime_start;

_LARGE_INTEGERtime_over;

doubledqFreq;

LARGE_INTEGERf;

QueryPerformanceFrequency(&f);

dqFreq=(double)f.QuadPart;

QueryPerformanceCounter(&time_start);

Node*s,

*newhead,

*p,

*pre,

*min;

s=head;

newhead=NULL;b1+=2;

while(s!

=NULL)

{

a1++,b1+=3;

min=s;

p=newhead;

while(p!

=NULL&&p->datadata){pre=p,p=p->next;b1+=2,a1+=2;}

s=s->next;

if(p==newhead)

{

a1++,b1+=2;

newhead=min;

newhead->next=p;

}

else

{

a1++,b1+=2;

pre->next=min;

min->next=p;

}

}

QueryPerformanceCounter(&time_over);

returnnewhead;

}

该算法的时间复杂度T(N)=O(N2)

(4)冒泡排序算法:

Node*Ebullient_Sort_LinkTable(Node*head)

{

_LARGE_INTEGERtime_start;

_LARGE_INTEGERtime_over;

doubledqFreq;

LARGE_INTEGERf;

QueryPerformanceFrequency(&f);

dqFreq=(double)f.QuadPart;

QueryPerformanceCounter(&time_start);

Node*q,

*tail,

*p,

*t;

q=newNode;

q->next=head;

head=q;b2+=3;

for(tail=NULL;tail!

=head;tail=p)

{

b2+=2,a2+=2;

for(p=q=head;q->next->next!

=tail;q=q->next)

{

b2+=3,a2+=2;

if(q->next->data>q->next->next->data)

{

a2++,b2+=5;

t=q->next->next;

q->next->next=t->next;

t->next=q->next;

q->next=t;

p=q->next->next;

}

}

}

q=head;

head=head->next;b2+=2;

deleteq;

QueryPerformanceCounter(&time_over);

returnhead;

}

该算法的时间复杂度T(N)=O(N2)

(5)快速排序算法:

Node*Fast_Sort_LinkTable(Node*head,Node*tail)

{

_LARGE_INTEGERtime_start;

_LARGE_INTEGERtime_over;

doubledqFreq;

LARGE_INTEGERf;

QueryPerformanceFrequency(&f);

dqFreq=(double)f.QuadPart;

QueryPerformanceCounter(&time_start);

if(head==NULL||tail==NULL)returnNULL;

if(head==tail)returnNULL;

Node*p,

*r,

*pre;

pre=head;

p=head->next;

r=head;b3+=3;

while(p&&p!

=tail->next)

{

a3+=2;

if(p->data<=head->data)

{

a3++,b3+=5;

r=pre;

pre=pre->next;

swamp(pre->data,p->data);

}

p=p->next;b3++;

}

swamp(head->data,pre->data);b3+=3;

Fast_Sort_LinkTable(head,r);

Fast_Sort_LinkTable(pre->next,tail);

QueryPerformanceCounter(&time_over);

returnhead;

}

该算法的时间复杂度T(N)=O(NlogN)

(6)简单选择排序算法:

Node*Select_Sort_LinkTable(Node*head)

{

_LARGE_INTEGERtime_start;

_LARGE_INTEGERtime_over;

doubledqFreq;

LARGE_INTEGERf;

QueryPerformanceFrequency(&f);

dqFreq=(double)f.QuadPart;

QueryPerformanceCounter(&time_start);

Node*newhead,

*tail,

*p,

*pre,

*min;

newhead=NULL;b4++;

while(head!

=NULL)

{

a4++;

for(p=min=head;p->next!

=NULL;p=p->next)

{

a4++,b4+=3;

if(p->next->datadata)

{

a4++,b4+=2;

pre=p;

min=p->next;

}

}

if(min==head){head=head->next;a4++,b4++;}

else{pre->next=min->next;a4++,b4++;}

if(newhead==NULL){tail=newhead=min;a4++,b4++;}

else{tail=tail->next=min;a4++,b4++;

}

if(newhead!

=NULL){tail->next=NULL;a4++,b4++;}

QueryPerformanceCounter(&time_over);

returnnewhead;

}

该算法的时间复杂度T(N)=O(N2)

2.3其他

由于程序源代码在上述时间复杂度分析中已基本全部提及,此处不再附加。

3.程序运行结果

1.测试主函数流程:

2.测试条件:

如上图所示,输入的数据为10个乱序数据:

45,678,22,4,17,98,77,56,234,780。

3.测试结论:

依次测试了插入排序,冒泡排序,快速排序,简单选择排序,结果都为正序,而且全部给出了算法运行时间和关键字的比较及移动次数,应可得出函数正常工作的结论。

4.总结

1.调试时出现的问题及解决办法:

(1)由于选择的是第二个,书上没有任何的参考代码,甚至在一些存储和实现方法上由于使用的是链表,因而出现了和数组不太一样的思想。

遇到的第一个难题是插入排序,因为使用的是单链表,不可能从后往前遍历,所以不适合使用书上的插入排序算法,对此我做了一些调整,把每次往前寻找改成每次从头往后寻找合适的插入点,由于测试数据包括正序、乱序、逆序,因此这样修改并不会导致算法整体时间复杂度的增加。

(2)第二个遇到的问题是快速排序算法,按照书上的算法,快速排序需要从双向往中间靠拢,最后定下权值的位置,对此我曾一度想要改成用双向链表存储数据以实现书上的算法。

但是后来感觉到这样会使整个程序显得异常臃肿(编完还需要加入时间算法和关键字统计算法),于是我又上网搜了一下,发现单链表的快速排序是有的,和书上的改进的快速排序算法思想是一样的,先将所有的数据根据权值左右分开,最后留下中间的位置给权值,然后不断递归求得最终结果。

根据这个思想我顺利地编出了快速排序的算法。

(3)在加入时间函数的时候也出现了一些问题,这主要是由于缺乏经验,不知道什么样的函数能够显示微秒级别的程序运行时间,这个问题在和同学讨论并上网搜索的过程中顺利地解决了。

(4)再有就是关键字的统计方面,由于是最后加入,所以从整个程序来看,加入了8个静态全局变量,用来分别记录4个排序算法的关键字比较次数和移动次数。

在具体的函数内部实现上,可能由于测试数据数量太小,线性或者平方的关系表现的并不是很明显。

2.心得体会:

这次编写代码延续了上次编写哈夫曼的良好风格,几乎是全程独自编写,只参考了网上的个别算法思想。

这对我的编程能力又是一次极大的加强,以前编的程序简单,可以参考的代码多,几乎编出来的就已经是正确的,几乎很少调试。

但是现在全是自己编,出现的问题很多,经常编译出来是一长串的问题,即时编译通过,运行时也经常达不到想要的效果,所以不得不多次使用但不调试F11来查找程序错误。

在这个过程中有苦有乐,但是不管怎样,编译通过,运行成功那一时刻的喜悦,我想每一个喜欢编程的人都是能够理解的!

3.下一步的改进:

其实有个第五项其他选项我没有完成,原因是虽然只编4个函数,但已花费了大量时间。

从时间上来说确实是不允许的。

如果时间足够,我想再多编几个函数,实现链表的其他排序。

话又说回来,链表的排序确实没有数组来的方便,我想有机会还是多和书上的数组的排序算法亲近亲近。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2