博主在考研复习数据结构时,根据严蔚敏老师的《数据结构》,重构了代码。最开始的代码(代码2)参考自《C语言教程》是一个类似封装好的链表实现。这份新的代码大部分参考自严蔚敏老师的《数据结构》,加入了自己的理解。
系统提供增、删、查、改、看 五项操作
初成代码,如果有BUG 还望指出,共同学习。
代码一:
带头结点的单链表实现。
#include<bits/stdc++.h>
using namespace std;
#define line cout << "-----------------" << endl
#define Status bool
#define ElemType LNode
typedef struct LNode{
char id[15];
char name[20];
double score;
struct LNode *next;
}LNode, *LinkList;
LinkList L;
int sum;
void CreatList(LinkList &L, int n){//后插法创建单链表
L = new LNode;
L->next = NULL;
LNode *r = L;
for(int i = 0; i < n; i++){
LNode *p = new LNode;
scanf("%s %s %lf", p->id, p->name, &p->score);
p->next = NULL;
r->next = p;
r = p;
}
}
void PrintList(LinkList &L){
printf("学号:\t姓名:\t成绩:\n");
LNode *p = L->next;
while(p != NULL){
printf("%s\t%s\t%lf\n", p->id, p->name, p->score);
p = p->next;
}
}
void ListFind(LinkList, char s[]){
LNode *p = L->next;
int j = 0;
while(p != NULL){
if(strcmp(p->id, s)== 0){
printf("学号:\t姓名:\t成绩:\n");
printf("%s\t%s\t%lf\n", p->id, p->name, p->score);
printf("查找成功\n");
return;
}
p = p->next;
j++;
}
printf("查找失败,请核查信息是否正确\n");
return;
}
/*
Status GetElem(LinkList L, int i, ElemType &e){
LNode *p = L->next;
int j = 1;
while(p && j < i){
p = p->next;
j++;
}
if(!p || j > i) return false;
e = p - > date;
return true;
}
LNode *LocateElem(LinkList L, ElemType e){
LNOde *p = L->next;
while(p && p->data != e){
p = p->next;
}
return p;
}
*/
Status ListInsert(LinkList &L, int i, ElemType *e){
sum ++;
LNode *p = L;
int j = 0;
while(p && (j < i-1)){
p = p->next;
j++;
}
if(!p || j > i-1) {
printf("插入失败,请核查信息是否正确\n");
return false;
}
LNode *s = new LNode;
s = e;
s->next = p->next;
p->next = s;
printf("插入成功\n\n");
return true;
}
Status ListDelete(LinkList &L, int i){
sum--;
LNode *p = L;
int j = 0;
while((p->next) && (j<i-1)){
p = p->next;
j++;
}
if(!(p->next) || (j > i-1) ){
printf("删除失败,请核查信息是否正确\n");
return false;
}
LNode *q = p->next;
p->next = q->next;
delete q;
return true;
}
Status ListChange(LinkList &L, int i, ElemType *e){
LNode *p = L;
int j = 0;
while((p->next) && (j<i-1)){
p = p->next;
j++;
}
if(!(p->next) || (j > i-1) ){
printf("查找失败,请核查信息是否正确\n");
return false;
}
p = p->next;
strcpy(p->id, e->id);
strcpy(p->name, e->name);
p->score = e->score;
printf("修改成功\n");
return true;
}
int main(){
printf("欢迎使用学生成绩管理系统:\n");
printf("本系统由带头结点的单链表实现\n");
printf("首次进入系统请先输入数据\n\n");
printf("请输入学生总人数:\n");
cin >> sum;
line;
printf("请依次输入学生的学号、姓名和成绩\n");
CreatList(L, sum);
printf("初始化成功!\n");
PrintList(L);
printf("系统提供增、删、查、改、看 五项操作\n");
char op[2];
printf("请选择您所需要的操作:\n");
printf("输入1:增加学生信息\n");
printf("输入2:删除学生信息\n");
printf("输入3:查找学生信息\n");
printf("输入4:修改学生信息\n");
printf("输入5:查看系统数据\n");
printf("输入#:退出系统\n");
scanf("%s", op);
while(true){
if(op[0] == '1'){
LNode *x = new LNode;
int pos = -1;
printf("请依次输入插入学生的学号、姓名和成绩\n");
scanf("%s %s %lf", x->id, x->name, &x->score);
x->next = NULL;
printf("请输入插入的位置\n");
scanf("%d", &pos);
ListInsert(L, pos, x);
}
else if(op[0] =='2'){
int pos = -1;
printf("请输入要删除的学生的位置\n");
scanf("%d", &pos);
ListDelete(L, pos);
}
else if(op[0] =='3'){
printf("请输入要查找的学生的学号:\n");
char s[20];
scanf("%s", s);
ListFind(L, s);
}
else if(op[0] =='4'){
LNode *x = new LNode;
int pos = -1;
printf("请依次输入插入修改后学生的学号、姓名和成绩\n");
scanf("%s %s %lf", x->id, x->name, &x->score);
x->next = NULL;
printf("请输入要修改的学生的位置\n");
scanf("%d", &pos);
ListChange(L, pos, x);
}
else if(op[0] =='5') PrintList(L);
else if(op[0] =='#') break;
else printf("错误输入\n");
printf("\n\n请选择您所需要的操作:\n");
printf("输入1:增加学生信息\n");
printf("输入2:删除学生信息\n");
printf("输入3:查找学生信息\n");
printf("输入4:修改学生信息\n");
printf("输入5:查看系统数据\n");
printf("输入#:退出系统\n");
scanf("%s", op);
}
printf("感谢您使用学生成绩管理系统。\n");
printf("\t\t\t作者 : 辞树");
return 0;
}
代码二:
#include<bits/stdc++.h>
#define LEN sizeof(struct stu)
using namespace std;
struct stu
{
int num; //学生学号
char name[20]; //学生姓名
float score; //学生成绩
struct stu *next; //指针后移
};
struct stu *creat() //创建链表
{
struct stu *head; //头指针
struct stu *p; //临时指针
struct stu *tail; //尾指针
int x;
tail = head = NULL; //将头尾指针初始化
scanf("%d",&x); //x为学生的学号
while(x!=0)
{
p = (struct stu *)malloc(LEN);
p->num = x;
if(head == NULL)
head = p;
scanf("%s %f",p->name,&p->score);
if(tail != NULL)
tail->next = p;
tail = p;
scanf("%d",&x);
}
if(tail != NULL)
tail -> next = NULL;
return (head);
}
struct stu *Insert(struct stu *head,struct stu *stud) //插入新的结点 *head 指向链表的首地址,stud为要插入的学生的结构体的地址
{
struct stu *p0; //p0指向要插入的新节点
struct stu *p1; //p1指向链表中第一个学号大于新节点的学号的节点
struct stu *p2; //p2指向p1的前驱节点,即p2的next域指向p1
p0 = stud; //新节点的地址
p1 = head; //链表的首地址给p1
if(head == NULL) //如果头指针不存在
{
head = p0; //就把新插入的指针地址设置为首地址,新插入的指针的尾指针指向空
p0->next=NULL;
}
else
{
while((p1!=NULL)&&(p0->num >= p1->num)) //查找。两个条件的顺序不能对调,否则p1的值为NULL时,还要再访问p1->num,将出现访问零地址的错误
{ //找到第一个成立的
p2 = p1;
p1 = p1->next;
}
if(p1!=NULL) //如果不是刚好插入链表的尾部
{
if(head == p1) //如果p0->num == p1->num 的情况成立
head = p0;
else // 如果p0->num == p1->num 的情况不成立
p2->next=p0;
p0->next=p1;
}
else //如果要插入的刚好是在链表的尾部
{
p2->next=p0;
p0->next=NULL;
}
}
return head; //返回插入学生的地址
}
struct stu *del(struct stu *head ,int num)
{
struct stu *p1;
struct stu *p2;
if(head == NULL)
printf("链表为空\n");
else
{
p1 = head;
while(p1!=NULL&&p1->num!=num)
{
p2=p1;
p1=p1->next;
}
if(p1->num==num)
{
if(p1==head)
head=p1->next;
else
p2->next=p1->next;
printf("删除的学生的学号:%d\n",num);
free(p1);
}
else
{
printf("学号为%d的学生没有被找到!\n");
}
}
return (head);
}
void List(struct stu *head)
{
struct stu *p;
p = head;
if(head !=NULL)
{
printf("学生的成绩列表为:\n");
printf("学号\t姓名\t成绩\n");
do
{
printf("%d\t%s\t%5.1f\n",p->num,p->name,p->score);
p = p->next; //p指针后移
}while(p!=NULL);
}
else
{
printf("链表为空\n\n");
}
cout<<endl<<endl;
}
int main()
{
printf("\t\t······欢迎来到学生成绩管理系统······\n\n");
printf("首次进入系统请先输入数据\n\n");
printf("请依次输入学生的学号、姓名和成绩(当输入的学号为0时,输入数据结束)\n");
struct stu *head;
head = creat();
List(head);
int temp;
printf("请选择需要进行的操作:\n");
printf("不需要更改请输入“0”\n");
printf("对学生的信息进行修改请输入“1”\n");
printf("查找学生的信息请输入“2”\n");
scanf("%d",&temp);
while(temp)
{
if(temp==1)
{
printf("请选择需要修改的内容:\n");
printf("增加学生数据请输入“1”\n");
printf("删除学生数据请输入“2”\n");
printf("更改学生数据请输入“3”\n");
int te;
scanf("%d",&te);
if(te==1) //增加学生数据
{
struct stu *newstu;
printf("请输入学生学号、姓名和成绩(输入学号为0时,输入结束)\n");
int num;
//head = NULL;
scanf("%d",&num);
while(num!=0)
{
newstu=(struct stu *)malloc(sizeof(struct stu));
newstu->num=num;
scanf("%s %f",newstu->name,&newstu->score);
head = Insert(head,newstu);
scanf("%d",&num);
}
List(head);
}
else if(te == 2) //删除学生数据
{
struct stu *newstu;
int num;
printf("请输入需要删除的学生的学号:\n");
scanf("%d",&num);
head = del(head,num);
List (head);
}
else if(te == 3) //更改学生数据
{
printf("请输入需要更改的学生的学号和成绩:\n");
int tt,ts;
scanf("%d%d",&tt,&ts);
struct stu *p;
p=head;
while(p->num!=tt)
p=p->next;
p->score=ts;
printf("修改成功\n");
printf("该生的个人信息如下:\n");
printf("学号\t姓名\t成绩\n");
printf("%d\t%s\t%f\n\n",p->num,p->name,p->score);
}
}
else if(temp == 2) //查找学生
{
struct stu *p;
p = head;
// int flag=0;
printf("请输入需要查找的学生的学号:\n");
int se;
scanf("%d",&se);
printf("该生的个人信息如下:\n");
printf("学号\t姓名\t成绩\n");
while(p&&p->num!=se)
{
p=p->next;
}
if(!p->num)
printf("查无此人!\n");
else
printf("%d\t%s\t%f\n\n",p->num,p->name,p->score);
}
printf("请选择需要进行的操作:\n\n");
printf("不需要更改请输入“0”\n");
printf("对学生的信息进行修改请输入“1”\n");
printf("查找学生的信息请输入“2”\n");
scanf("%d",&temp);
}
List(head);
printf("感谢您使用学生成绩管理系统,欢迎再次使用\n");
printf("\t\t\t\t\t\t作者:辞树\n\n");
return 0;
}