#include<iostream>
#include<time.h>
#include<Windows.h>
using namespace std;
#define NUM 100
#pragma warning(disable:4996)
typedef struct student
{
int num;
char name[10];
float score;
}stu;
typedef struct list
{
stu data;
struct list *next;
}List;
void ooopennode(List *&L);//初始化表头方法①
void oopennode(List *L);//初始化表头方法②
void Opennode(List **L);//初始化表头方法③
List* opennode();//初始化表头方法④
/*【心得】指针和变量一样,都需要初始化才可以对其进行修改,即传实参时,此指针或者变量
需要有意义,可以参照这三种指针初始化在主函数中写法的区别*/
void insertlist(List *La, stu data); //选择头插法,提高效率【注】:此处是将注释A处的两个函数合并成一个,提高运算效率
void getlist(List *L, int num);//取对应位置的数据
void findlist(List *L, int num);//根据学号查对应学生信息
int getlength(List *L);//求链表的长度
void orderbylist(List *L);//根据成绩对学生信息进行排序,排序思路:在链表内进行冒泡排序
void Orderbylist(List *L);/*根据成绩对学生信息进行排序, 排序思路:先将链表数据域赋值到结构体数组中,然后在数组中排序完再重新
赋值回链表数据域*/
void deletelist(List *L, int num);//删除对应学号的节点
void emptylist(List *L);//清空链表
void printflist(List *L);//打印链表
void destroylist(List *L);//销毁链表
int main()
{
int num;
char x;
stu student;
//List *L; ooopennode(L);//第一种初始化方式
//List *L = new List; oopennode(L);//第二种初始化方式
//List *L; Opennode(&L);//第三种初始化方式
List *L = opennode();//第四种初始化方式
while (1)
{
cout << "请输入学生的学号和姓名以及成绩:";
cin >> student.num >> student.name>> student.score;
insertlist(L, student);
cout << "是否继续录入(Y/N)";
cin >> x;
if (x == 'N')break;
}
Orderbylist(L);
cout << "学生信息如下:" << endl;
printflist(L);
system("pause");
cout << "请输入你要查询的数据位置:";
cin>>num;
getlist(L, num);
cout << "请输入你需要查找学生的学号:";
cin >> num;
findlist(L, num);
cout << "请输入需要删除学生的学号:";
cin >> num;
deletelist(L, num);
cout << "删除后学生信息如下:" << endl;
printflist(L);
destroylist(L);
return 0;
}
void ooopennode(List *&L)//初始化表头方法①
{
L = new List;
L->next = NULL;
}
void oopennode(List *L)//初始化表头方法②
{
L->next = NULL;
}
void Opennode(List **L)//初始化表头方法③
{
*L = new List;
(*L)->next = NULL;
}
List* opennode()//初始化表头方法④
{
List *L = new List;
L->next = NULL;
return L;
}
/*void createlist(List *L,stu data)//初始化节点,以便插入时调入
{
L = new List;
L->data = data;
L->next = NULL;
}
void insertlist(List *La,List *Lb)//选择头插法,提高效率
{
Lb->next = La->next;
La->next = Lb;
}A处*/
void insertlist(List *La, stu data)//选择头插法,提高效率【注】:此处是将注释A处的两个函数合并成一个,提高运算效率
{
List *L = new List;
L->data = data;
L->next = La->next;
La->next = L;
}
void getlist(List *L, int num)//取对应位置的数据
{
List *p = L->next;
int count = 1;
while(p&&count < num)
{
p = p->next;
count++;
}
if (!p || count > num)cout << "暂无数据" << endl;
else {
cout << "学生信息如下:" << endl;
cout << "-------------------------------------------- " << endl;
cout << "|学号:" << p->data.num << "| |" << "姓名:" << p->data.name << "| |" << "成绩:" << p->data.score << "|" << endl;
cout << "-------------------------------------------- " << endl;
}
}
void findlist(List *L, int num)//根据学号查对应学生信息
{
List *p = L->next;
while (p&&p->data.num != num)
{
p = p->next;
}
if (!p )cout << "暂无数据" << endl;
else
{
cout << "学生信息如下:" << endl;
cout << "-------------------------------------------- " << endl;
cout<<"|学号:"<< p->data.num <<"| |"<<"姓名:" << p->data.name << "| |"<< "成绩:" << p->data.score <<"|"<< endl;
cout << "-------------------------------------------- " << endl;
}
}
int getlength(List *L)//求链表的长度
{
List *p = L->next;
int count = 0;
while(p)
{
p = p->next;
count++;
}
return count;
}
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;
}
}
}
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;
}
}
void deletelist(List *L, int num)//删除对应学号的节点
{
List *p = L;
List *q = L->next;
if (q == NULL)cout << "链表为空,无法删除" << endl;
while (q&&q->data.num != num)
{
p = p->next;
q = q->next;
if (q == NULL)cout << "找不到指定位置" << endl;
}
p->next = q->next;
delete q;
}
void emptylist(List *L)//清空链表
{
List *p, *q;
p = L->next;
while (p)
{
q = p->next;
delete p;
p = q;
}
L->next = NULL;
}
void destroylist(List *L)//销毁链表
{
List *p ;
while (L)
{
p = L;
L = L->next;
delete p;
}
}
void printflist(List *L)//打印链表
{
List *p = L->next;
cout << "---------------------------------" << endl;
cout << "| 学号 " << " |" << " 姓名 " << "|" << " 成绩 |" << endl;
while (p)
{
if(strlen(p->data.name)==4)
cout << "|" << p->data.num << "| " << p->data.name << " | " << p->data.score << " |" << endl;
if (strlen(p->data.name) == 6)
cout <<"|"<< p->data.num << "| " << p->data.name << " | " << p->data.score <<" |"<< endl;
p = p->next;
cout << "---------------------------------" << endl;
}
}
上图是对应代码的运行结果