单向链表中的数据排序问题


前言

在利用单链表做学生信息管理系统的时候发现了一个一直忽略一个问题,就是在单链表中如何进行排序的问题,我们知道在顺序表中可以很轻易的利用冒泡排序或者归并排序等各种算法轻易实现排序,但在单链表中该如何进行排序引起了我的思考。在一番思索过后,我暂时给出了两种基本的解决方案,这两种方案我都放在了之前的一篇文章中,详细代码可以参考数据结构——(线性表之单链表)学生信息应用这篇文章。


一、单向链表中数据排序问题的解决方案

算法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更好。
   进一步可以得出,在链表中的排序时间复杂度要远高于在顺序表中的时间复杂度,所以较为快速的排序方法是把单链表中的所有数据域全部取出放到结构体数组中进行排序,再按照顺序重新录入链表

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值