單向連結串列中的資料排序問題
阿新 • • 發佈:2021-01-27
文章目錄
前言
在利用單鏈表做學生資訊管理系統的時候發現了一個一直忽略一個問題,就是在單鏈表中如何進行排序的問題,我們知道在順序表中可以很輕易的利用氣泡排序或者歸併排序等各種演算法輕易實現排序,但在單鏈表中該如何進行排序引起了我的思考。在一番思索過後,我暫時給出了兩種基本的解決方案,這兩種方案我都放在了之前的一篇文章中,詳細程式碼可以參考資料結構——(線性表之單鏈表)學生資訊應用這篇文章。
一、單向連結串列中資料排序問題的解決方案
演算法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更好。
進一步可以得出,在連結串列中的排序時間複雜度要遠高於在順序表中的時間複雜度,所以較為快速的排序方法是把單鏈表中的所有資料域全部取出放到結構體陣列中進行排序,再按照順序重新錄入連結串列