連結串列的帶引數排序,可以通過姓名、成績進行升序或降序操作
阿新 • • 發佈:2018-12-25
先上效果圖:
void main()
{
stu * pHeader = creatLink(4); //建立連結串列,需要手動輸入姓名成績
sort(pHeader, true, COMPARE_SCORE); //按照成績升序排列
outLink(pHeader); //控制檯上輸出連結串列
clearLink(pHeader); //清空連結串列
}
紅框部分即為成績升序排列
/*
連結串列排序,支援帶引數的排序,
可以通過改變引數來實現根據成績排序、根據姓名排序,
並且可以升序降序,如下:
*/
#define COMPARE_SCORE 0 //比較成績
#define COMPARE_NAME 1 //比較姓名
struct stu
{
char name[24];
int score;
stu * next;
};
//所用到的工具方法宣告,具體實現見尾部
int MyStrCmp(const char * str1, const char * str2); //比較字串
void swapEle(stu * p0, stu * p2); //交換連結串列元素
int cmpEle(stu * s1, stu * s2, int nFlag); //比較連結串列元素
// 建立連結串列,並將連結串列初始化,需要手動輸入引數
stu * creatLink(int nCount)
{
stu * pHeader = new stu;
strcpy_s(pHeader->name, "start");
pHeader->next = NULL;
stu * pTemp = pHeader;
cout << "請按照如下格式輸入學生資訊: 姓名 (回車鍵) 成績" << endl;
for (int i = 0; i < nCount; i++)
{
pHeader->next = new stu;
pHeader->next->next = NULL ;
pHeader = pHeader->next;
cout << "請輸入資訊: ";
cin >> pHeader->name;
cin >> pHeader->score;
}
return pTemp;
}
/*
連結串列升降序,
bAscend為true時升序,為false時降序
nFlag用與傳入需要比較的引數,
如COMPARE_SCORE, COMPARE_NAME
*/
void sort(stu * pHeader, bool bAscend, int nFlag)
{
int nJudge = bDescend ? 1 : -1; //nJudge用於決定升降序
if (NULL == pHeader || NULL == pHeader->next || NULL == pHeader->next->next)
return;
stu * pTemp = pHeader;
stu * pEnd = NULL;
stu * p0 = pHeader->next;
stu * p1 = pHeader->next->next;
while (pEnd != p1)
{
while (pEnd != p1)
{
if (nJudge == cmpEle(p0, p1, nFlag)) //敲黑板,劃重點,此處使程式碼更加容易功能擴充和維護
swapEle(pHeader, p1);
pHeader = pHeader->next;
p0 = pHeader->next;
p1 = p0->next;
}
pEnd = p0;
pHeader = pTemp;
p0 = pHeader->next;
p1 = p0->next;
}
}
// 將連結串列輸出
void outLink(stu * pHeader)
{
pHeader = pHeader->next;
while (NULL != pHeader)
{
cout << pHeader->name << "\t" << pHeader->score << endl;
pHeader = pHeader->next;
}
}
// 清空連結串列
void clearLink(stu * pHeader)
{
stu * pTemp = pHeader;
while (NULL != pHeader)
{
pTemp = pHeader->next;
delete pHeader;
pHeader = pTemp;
}
delete pHeader;
}
/*
工具類方法的實現
*/
// 字串比較
int MyStrCmp(const char * str1, const char * str2)
{
while (*str1)
{
if (*str1 > *str2)
{
return 1;
}
if (*str1 == *str2)
{
if (*(str1 + 1) == NULL && *(str2 + 1) == NULL)
return 0;
if (*(str1 + 1) != NULL && *(str2 + 1) == NULL)
return 1;
++str2;
++str1;
continue;
}
if (*str1 < *str2)
{
return -1;
}
}
return -1;
}
// 交換連結串列元素(注意傳入連結串列節點不是連續的,中間有間隔)
void swapEle(stu * p0, stu * p2)
{
stu * p3 = p2->next;
stu * p1 = p0->next;
p0->next = p2;
p2->next = p1;
p1->next = p3;
}
// 比較連結串列元素
int cmpEle(stu * s1, stu * s2, int nFlag)
{
int nCtrl = 0;
switch (nFlag)
{
case COMPARE_SCORE:
nCtrl = s1->score > s2->score ? 1 : -1;
break;
case COMPARE_NAME:
nCtrl = MyStrCmp(s1->name, s2->name);
}
return nCtrl;
}