前言
在利用单链表做学生信息管理系统的时候发现了一个一直忽略一个问题,就是在单链表中如何进行排序的问题,我们知道在顺序表中可以很轻易的利用冒泡排序或者归并排序等各种算法轻易实现排序,但在单链表中该如何进行排序引起了我的思考。在一番思索过后,我暂时给出了两种基本的解决方案,这两种方案我都放在了之前的一篇文章中,详细代码可以参考数据结构——(线性表之单链表)学生信息应用这篇文章。
一、单向链表中数据排序问题的解决方案
算法A
代码如下
void orderbylist(List *L)//根据成绩对学生信息进行排序,排序思路:在链表内进行冒泡排序
{
int count = getlength(L);
stu data;
List *p = L->next;
for (int i = 0; i < count; i++)
{
p = L->next;
for (int j = 0; j < count - 1 - i; j++)
{
if (p->data.score < p->next->data.score)
{
data = p->next->data;
p->next->data = p->data;
p->data = data;
}
p = p->next;
}
}
}
算法B
代码如下
void Orderbylist(List *L)/*根据成绩对学生信息进行排序, 排序思路:先将链表数据域赋值到结构体数组中,然后在数组中排序完再重新
赋值回链表数据域*/
{
List *p = L->next;
int count = getlength(L);
if (count > NUM)cout << "链表过长,无法排序" << endl;
stu student[NUM];
stu data;
for (int i = 0; i < count; i++)
{
student[i] = p->data;
p = p->next;
}
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count - i - 1; j++)
{
if (student[j].score < student[j + 1].score)
{
data = student[j + 1];
student[j + 1] = student[j];
student[j] = data;
}
}
}
p = L->next;
for (int i = 0; i < count; i++)
{
p->data = student[i];
p = p->next;
}
}
二、算法优劣比较
1.运用GetTickCount()函数来记录两种方法在同一长度链表排序中的时间
代码如下:
#include<iostream>
#include<time.h>
#include<Windows.h>
using namespace std;
#define NUM 10000
#pragma warning(disable:4996)
int main()
{
DWORD startTime = GetTickCount();//计时开始
List *L = opennode();
stu student0, student1, student2, student3, student4;
student0.num = 2020120500; strcpy(student0.name, "张亮"); student0.score = 70;
student1.num = 2020120501; strcpy(student1.name, "王刚"); student1.score = 100;
student2.num = 2020120502; strcpy(student2.name, "李强"); student2.score = 95;
student3.num = 2020120503; strcpy(student3.name, "刘佳佳"); student3.score = 99;
student4.num = 2020120504; strcpy(student4.name, "徐子涛"); student4.score = 80;
for (int i = 0; i < 500; i++)
{
insertlist(L, student0); insertlist(L, student1); insertlist(L, student2);
insertlist(L, student3); insertlist(L, student4);
orderbylist(L);//Orderbylist(L);
}
DWORD endTime = GetTickCount();//计时结束
cout << "The run time is:" << endTime - startTime << "ms" << endl;
cout << getlength(L) << endl;
system("pause");
destroylist(L);
return 0;
}
2.记录结果和比较
算法A的时间记录:
算法B的时间记录:
总结
根据以上的实验结果可以很明显的看出来,算法A的时间远大于算法B,即算法B更好。
进一步可以得出,在链表中的排序时间复杂度要远高于在顺序表中的时间复杂度,所以较为快速的排序方法是把单链表中的所有数据域全部取出放到结构体数组中进行排序,再按照顺序重新录入链表