}
该算法的时间复杂度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个函数,但已花费了大量时间。
从时间上来说确实是不允许的。
如果时间足够,我想再多编几个函数,实现链表的其他排序。
话又说回来,链表的排序确实没有数组来的方便,我想有机会还是多和书上的数组的排序算法亲近亲近。