void menu()
{
printf("**********************************************************\n");
printf("1数据的创建 \t2数据的插入\t3数据的删除\n4数据的更改\t5求数据最大值\t6数据的排序\n7输出数据\t8退出\t\
9清屏\n");
printf("********************************************************\n");
}
#二、每个函数的简绍与思路
##1:密码登录的验证思路:
(1)在主函数main里定义一个标志 flat2=0;如果flat2!=0,就代表密码登录成功,可以进入系统!
(2)在具体函数mima()之中,使用了控制台函数_getch();其头文件为#include<conio.h>,该函数可以隐藏输出,注意:_getch()是隐藏单个字符,且需要一个存储空间,可以使用数组结合循环来使用,例子a[i]=_getch();此时在终端上不会显示内容,所以结合printf语句让用户明白我们输入的多少!并且加入判断,回车是结束输入的功能并且给此时空间赋值一个’\0’!
定义一个j是保证最大的失误范围若超过系统退出!
(3)删除功能是:当输入回车时,阻止继续输入*,(使用continue);,并且给此时空间赋值一个’\0’,
在进行printf(“\b”);鼠标箭头回退,printf(" “);输入空格覆盖 “*”;在让鼠标回退printf(”\b");
代码如下
void mima(int* flag2)
{
int j = 6;
char mima[20];
int i = 0;
while (1)
{
i = 0;
printf("请输入用户名:");
char name[16];
scanf("%s", name);
printf("请输入密码:");
while (1)
{
mima[i] = _getch();
if (mima[i] == '\r')
{
mima[i] = '\0';
break;
}
else if (mima[i] == '\b')
{
mima[i] = '\0';
printf("\b");
printf(" ");
printf("\b");
i--;
continue;
}
else
{
printf("*");
i++;
if (i == 19)
{
printf("密码已达到最大长度!\n");
break;
}
}
}
if (strcmp(name, "小明") == 0)
{
if (strcmp(mima, "2082716421") == 0)
{
*flag2 = 2;
printf("输入正确!\n");
break;
}
else
{
j--;
printf("账户或密码错误!\n");
printf("你还有%d次机会\n", j);
if (j == 0)
{
printf("已达到输入密码最多次数\n");
break;
}
}
}
else
{
j--;
printf("查询不到用户!\n");
printf("你还有%d次机会\n", j);
if (j == 0)
{
printf("已达到输入密码最多次数\n");
break;
}
}
}
}
##创建链表
使用了一个单链表,链表思路如下:
(1)首先创建一个结构体;
typedef struct Date
{
int age[6];
char name[16];
int length;
}lp;//创建这个结构体是为了高效进行数据域交换的冒泡排序
typedef struct student
{
lp data;
struct student *next;
}Lp;(注意一般结构体里是不许赋初值的)
头节点head(这个是大基,不要动他,以后的操作函数传它,用它去进行插入,删除,输出等功能)且数据域不要存放东西,因为后续插入等操作要用到!,赋值链节p,p=head;新链节 q(指针);开辟他的空间,并使用p->next=q;在让p=q;q在去开辟空间重复上述功能!
注意的是,如果在函数内开辟空间,涉及到函数传参问题
思路1:使用函数指针且返回的是头节点。
Lp* Creatlist(Lp* head)
{
head = (Lp*)malloc(sizeof(Lp));//头节点不要在数据域存数据
Lp* p = head, * q = NULL;
head->data.length = 0;//确定链表的长度
while (1)
{
q = (Lp*)malloc(sizeof(Lp));
p->next = q;
p = q;
printf("请输入%d位学生姓名:", head->data.length + 1);
scanf("%s", p->data.name);
if (strcmp(p->data.name, "结束输入") == 0)
{
break;
}
printf("请输入%d位学生六科成绩:", head->data.length + 1);
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
scanf("%d", &p->data.a[i]);
}
head->data.length++;
}
p->next = NULL;
return head;
}
思路2: 传二级指针对一级指针的修改。
void creatlianbiao(ch** head, int* a)
{
*a = 0;//检验链接的长度
*head = (ch*)malloc(sizeof(ch));//开辟链表头的空间
ch* p = NULL, * q = NULL;
p = *head;
while (1)
{
printf("请输入姓名:");
scanf("%s", p->a.name);
if (strcmp(p->a.name, "退出") == 0)
{
break;
}
printf("请输入成绩:");
scanf("%d", & p->a.cj);
(*a)++;
q = (ch*)malloc(sizeof(ch));
p->next = q;
p = q;
}
p->next = NULL;
}
//思路如此,这个是一个姓名对应一个值
//这个没有插入等操作所以为了省空间头节点数据域存放了数据
##检验链表的开辟是否成功(遍历链表)
主要思路就是当p->next==NULL时,跳出循环;
void Outputlist(Lp* head)
{
Lp* p; p = head->next;//头节点没有数据所以是head->next;
while (p->next != NULL)
{
printf("%s:\t", p->data.name);
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
printf("%d\t", p->data.a[i]);
}
printf("\n");
p = p->next;
}
}
##3插入与删除,改变链表功能
思路:这三者基本一样,区别的是:插入需要找到目标后对其后或之前进行插入(会导致首节点,或末节点插入有些许困难),删除就是找到目标位置进行指针跳过这个指向后一节操作!而改变是在找到目标情况下进行修改具体如下
(1)插入:采用了查询姓名+首个成绩来找值,并在其后进行操作,这里分别给出插入某个人数据后面的和首位置得方法
Lp* Insertmenu(Lp* head)
{
int a=0;
Lp* Insertlist(Lp * head);
Lp* Inserfirsttlist(Lp * head);
void Outputlist(Lp * head);//声明函数
printf("***************************\n");
printf("1,插入首位\t2插入某个人数据后面\t3退出\t4输出\n");
while (a != 888)
{
printf("请输入你要选择插入的功能:");
scanf("%d", &a);
switch (a)
{
case 1:head = Inserfirsttlist(head); break;
case 2:head = Insertlist(head); break;
case 3: a = 888;//退出循环条件
break;
case 4:Outputlist(head); break;
default:printf("请输入1—4的数据"); break;
}
}
return head;
}
//插入链首的
Lp* Inserfirsttlist(Lp* head)
{
if (head == NULL)
{
printf("请先初始化在进行其他操作");
return head;
}//判断是否初始化创建链表
printf("你进入的是插入首链节选择!\n");
Lp* p, * q;
Lp* m = head->next;//存放首个数据域的节点
p = head;
q = (Lp*)malloc(sizeof(Lp));//开辟空间
printf("请输入插入的学生姓名:");
scanf("%s", q->data.name);
printf("请输入%该学生六科成绩:");
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
scanf("%d", &q->data.a[i]);
}
head->data.length++;//测长度
p->next = q;
q->next = m;
return head;
}
//插入某个数据的后面的
Lp* Insertlist(Lp* head)
{
if (head == NULL)
{
printf("请初始化在进行其他操作!");
return head;
}//检验是否位为空条件
char name[16];
int a;
printf("请输入要插入那个人的姓名+首个成绩:");
scanf("%s", name);
scanf("%d", &a);
Lp* p = head->next, * q;//头节点为指针域为空
Lp* m = head->next->next;//紧跟着存放p的后继位!方便插入
int k = 0;//检验是否找到数据
while (p->next != NULL)
{
if (strcmp(p->data.name, name) == 0 && p->data.a[0] == a)
{
printf("已成功找到要插入数据\n");
q = (Lp*)malloc(sizeof(Lp));
printf("请输入学生姓名:");
scanf("%s", q->data.name);
printf("请输入学生六科成绩:");
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
scanf("%d", &q->data.a[i]);
}
head->data.length++;//长度
p->next = q;
q->next = m;
k++;
break;//找到后直接跳出循环
}
else
{
p = p->next;
m = m->next;
}//保持链表向后进行
}
if (k == 0)
{
printf("未找到数据\n");
}
return head;
}
(2)删除(其实可以写一个函数完成,但是为了对称采用此方法)
Lp* Deletemenu(Lp* head)
{
void Outputlist(Lp * head);//声明
int a = 0;
printf("***************************\n");
printf("1,删除首位\t2删除某个人数据后面\t3退出\t4输出\n");
while (a != 888)
{
printf("请输入你要选择删除的功能:");
scanf("%d", &a);
switch (a)
{
case 1:head = Deletefirstlist(head); break;
case 2:head = Deletelist(head); break;
case 3: a = 888;//退出循环条件
break;
case 4:Outputlist(head); break;
default:printf("请输入1—4的数据"); break;
}
}
return head;
}
Lp* Deletefirstlist(Lp* head)
{
if (head == NULL)
{
printf("请先初始化在进行其他操作");
return head;
}//判断是否初始化创建链表
Lp* p = head;//用来跳过首个有数据的链结
Lp* q = head->next->next;//注意这里不在是开辟空间啦,这是有数据的链结后的链结
p->next = q;
head->data.length--;
return head;
}
Lp* Deletelist(Lp* head)
{
if (head == NULL)
{
printf("请先初始化在进行其他操作");
return head;
}//判断是否初始化创建链表
Lp* p = head;
Lp* q = head->next;//p后的链结
printf("请输入要插入那个人的姓名+首个成绩:");
char name[16];
int a;
int k = 0;//检验是否找到数据
scanf("%s", name);
scanf("%d", &a);
while (p->next != NULL)
{
if (strcmp(q->data.name, name) == 0 && q->data.a[0] == a)//这里不能用p->next来因为无法对目标数据进行处理
{
printf("已成功找到要插入数据\n");
p ->next = q->next;
k++;
head->data.length--;
break;
}
else
{
p = p->next;
q = q->next;
}
}
if (k == 0)
{
printf("未找到数据\n");
}
return head;
}
(3)改变链表数据(查到目标数据进行修改,可以借鉴这个进行另一种删除)
Lp* Chooselist(Lp* head)
{
if (head == NULL)
{
printf("请初始化在进行其他功能!");
return head;
}
Lp* p = head->next;
printf("请输入你要修改学生的姓名+首个成绩:");
char name[16];
scanf("%s", name);
int a;
scanf("%d", &a);
int k = 0;
while (p->next != NULL)
{
if (strcmp(p->data.name, name) == 0 && p->data.a[0] == a)
{
printf("查询到你要修改的数据\n");
printf("请输出要修改的数据的姓名:");
scanf("%s", p->data.name);
printf("请输入学生六科成绩:");
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
scanf("%d", &p->data.a[i]);
}
break;
}
else
{
p = p->next;
}
}
return head;
}
##求最值问题(按照总分大小进行比,但是写的是average不要介意呦!)
因为在排序中要用到总值函数所以设立两个函数!
注意:一定要给average赋初值(当时一直以为是排序问题,没想到出错在这)
Lp* Maxlist(Lp* head)
{
//这里在结构体里加了一个 int average 来进行比较
Lp* p = head->next;//因为头节点数据域为空
while (p->next != NULL)
{
for (int i = 0; i < sizeof(p->data.a) / sizeof(p->data.a[0]); i++)
{
p->data.average += p->data.a[i];
}
p = p->next;
}
return head;
}
void Maxoutput(Lp* head)
{
Lp* p;
p = head->next;
Lp *max=NULL;
max = p;
while (p->next != NULL)
{
if (p->data.average > max->data.average)
{
max = p;
}
p = p->next;
}
printf("%s:", max->data.name);
for (int i = 0; i < sizeof(p->data.a) / sizeof(p->data.a[0]); i++)
{
printf("%d\n", max->data.a[i]);
}
printf("\n");
}
##排序问题!!(服了,折腾我这么长时间)
排序算法(1,是进行数据域的交换,2是指针域的交换)
1数据域交换的思路:(采用的冒泡,这里区别的是在交换数据,直接把节点的数据域进行交换,推荐两个结构体)原来排序是i<n-1;这里直接改成p->next->next != NULL,并且内循环是q->next->next!=NULL;相比于下标这里没有了每次在内循环减一操作,
也可以用下标法,这里我们长度已经给了,亦可以用,(下标法没写,这个简单)
两者区别是:一个需要长度,另一个不需要长度
2:指针域交换的思路:我们已经测量了长度,就可以避免了q->NULL的交换了,这里我们交换不是设置中间变量的简单交换,例如p=head->next;q=p->next;交换后要写成,p->next=q->next;
q->next=p;!不推荐使用临时变量去交换!
因为p 和q 在动,我们要在往后遍历时推荐设一个第三方变量 move并且由move去引导进行两两相邻的比较!
3总结:指针域交换适合数据域非常大的时候,数据域交换适合数据域较少的因为涉及到数据域的拷贝
Lp* Sortkaozhilist(Lp* head)
{
printf("按照平均分从小到大的写法且按照拷贝数据域方法进行\n");
Lp* Maxlist(Lp * head);//声明
head = Maxlist(head);
Lp* p = head->next;//控制外循环
Lp* q = head->next;//控制内循环
for (; p->next->next != NULL; p = p->next)
{
for (q=head->next;q->next->next != NULL; q = q->next)//这样写有个不好的,这是是全部进行比较,不是每次少一个但是这样写的好处是不用测量长度!在数据少这样写的快
//这里我想了想设立了一个下标操作!这样写的好处是不用测量长度!
{
if (q->next != NULL || q != NULL)//防止越界
{
if (q->data.average > q->next->data.average)
{
lp t;//作为中间变量进行替换
t = q->data;
q->data = q->next->data;
q->next->data = t;
}
}
}
}
return head;
}
Lp* Sortzhizhenlist(Lp* head)
{
printf("进行的是指针域的改变按照从大到小(适合大数据)\n");
printf("并且是下标法的冒泡排序\n");
printf("请检验下标的数据为:%d\n", head->data.length);
Lp* Maxlist(Lp * head);//声明函数
head = Maxlist(head);
Lp* p = head->next;
Lp* q = head->next->next;//p的后节点
Lp* move=head;//因为p和q指针域发生变化,所以需要用move去遍历
for (int i = 0; i < head->data.length-1; i++)
{
p = head->next;
q = p->next;
move = head;//初始化
for (int j = 0; j < head->data.length - 1 - i; j++)
{
if (p->data.average <q->data.average)
{
p->next = q->next;//把p后面那个节点的指针域给p->next;
q->next = p;//原本时p指向q,现在是q指向p
move->next = q;//找到要移动的位置
}//交换相邻指针域使最少的放在后面;
move = move->next;//这样是每次往后进行相邻比较
p = move->next;
q = p->next;//往后移
}
}
return head;
}
Lp* sortmenu(Lp* head)
{
void Outputlist(Lp * head);//声明
int a = 0;
printf("***************************\n");
printf("1拷贝值排序(适合数据小的)\t2指针域排序(有点不同)\t3退出\t4输出\n");
while (a != 888)
{
printf("请输入你要选择排序的功能:");
scanf("%d", &a);
switch (a)
{
case 1:head = Sortkaozhilist(head); break;
case 2:head = Sortzhizhenlist(head); break;
case 3: a = 888;//退出循环条件
break;
case 4:Outputlist(head); break;
default:printf("请输入1—4的数据"); break;
}
}
return head;
}
##可运行总代码:文章来源:https://www.toymoban.com/news/detail-856008.html
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
typedef struct Data
{
int a[6];
char name[16];
int average;
int length;
}lp;//创建这个结构体是为了高效进行冒泡排序
typedef struct student
{
lp data;
struct student* next;
}Lp;
void mima(int* flag2)
{
int j = 6;
char mima[20];
int i = 0;
while (1)
{
i = 0;
printf("请输入用户名:");
char name[16];
scanf("%s", name);
printf("请输入密码:");
while (1)
{
mima[i] = _getch();
if (mima[i] == '\r')
{
mima[i] = '\0';
break;
}
else if (mima[i] == '\b')
{
mima[i] = '\0';
printf("\b");
printf(" ");
printf("\b");
i--;
continue;
}
else
{
printf("*");
i++;
if (i == 19)
{
printf("密码已达到最大长度!\n");
break;
}
}
}
if (strcmp(name, "小明") == 0)
{
if (strcmp(mima, "2082716421") == 0)
{
*flag2 = 2;
printf("输入正确!\n");
break;
}
else
{
j--;
printf("账户或密码错误!\n");
printf("你还有%d次机会\n", j);
if (j == 0)
{
printf("已达到输入密码最多次数\n");
break;
}
}
}
else
{
j--;
printf("查询不到用户!\n");
printf("你还有%d次机会\n", j);
if (j == 0)
{
printf("已达到输入密码最多次数\n");
break;
}
}
}
}
void menu()
{
printf("**********************************************************\n");
printf("1数据的创建 \t2数据的插入\t3数据的删除\n4数据的更改\t5求数据最大值\t6数据的排序\n7输出数据\t8退出\t\
9清屏\n");
printf("********************************************************\n");
}
Lp* Creatlist(Lp* head)
{
head = (Lp*)malloc(sizeof(Lp));//头节点不要在数据域存数据
Lp* p = head, * q = NULL;
head->data.length = 0;//确定链表的长度
while (1)
{
q = (Lp*)malloc(sizeof(Lp));
p->next = q;
p = q;
printf("请输入%d位学生姓名:", head->data.length + 1);
scanf("%s", p->data.name);
if (strcmp(p->data.name, "结束输入") == 0)
{
break;
}
printf("请输入%d位学生六科成绩:", head->data.length + 1);
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
scanf("%d", &p->data.a[i]);
}
head->data.length++;
}
p->next = NULL;
return head;
}
Lp* Insertmenu(Lp* head)
{
int a=0;
Lp* Insertlist(Lp * head);
Lp* Inserfirsttlist(Lp * head);
void Outputlist(Lp * head);//声明函数
printf("***************************\n");
printf("1,插入首位\t2插入某个人数据后面\t3退出\t4输出\n");
while (a != 888)
{
printf("请输入你要选择插入的功能:");
scanf("%d", &a);
switch (a)
{
case 1:head = Inserfirsttlist(head); break;
case 2:head = Insertlist(head); break;
case 3: a = 888;//退出循环条件
break;
case 4:Outputlist(head); break;
default:printf("请输入1—4的数据"); break;
}
}
return head;
}
Lp* Inserfirsttlist(Lp* head)
{
if (head == NULL)
{
printf("请先初始化在进行其他操作");
return head;
}//判断是否初始化创建链表
printf("你进入的是插入首链节选择!\n");
Lp* p, * q;
Lp* m = head->next;//存放首个数据域的节点
p = head;
q = (Lp*)malloc(sizeof(Lp));//开辟空间
printf("请输入插入的学生姓名:");
scanf("%s", q->data.name);
printf("请输入%该学生六科成绩:");
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
scanf("%d", &q->data.a[i]);
}
head->data.length++;//测长度
p->next = q;
q->next = m;
return head;
}
Lp* Insertlist(Lp* head)
{
if (head == NULL)
{
printf("请初始化在进行其他操作!");
return head;
}//检验是否位为空条件
char name[16];
int a;
printf("请输入要插入那个人的姓名+首个成绩:");
scanf("%s", name);
scanf("%d", &a);
Lp* p = head->next, * q;//头节点为指针域为空
Lp* m = head->next->next;//紧跟着存放p的后继位!方便插入
int k = 0;//检验是否找到数据
while (p->next != NULL)
{
if (strcmp(p->data.name, name) == 0 && p->data.a[0] == a)
{
printf("已成功找到要插入数据\n");
q = (Lp*)malloc(sizeof(Lp));
printf("请输入学生姓名:");
scanf("%s", q->data.name);
printf("请输入学生六科成绩:");
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
scanf("%d", &q->data.a[i]);
}
head->data.length++;//长度
p->next = q;
q->next = m;
k++;
break;//找到后直接跳出循环
}
else
{
p = p->next;
m = m->next;
}//保持链表向后进行
}
if (k == 0)
{
printf("未找到数据\n");
}
return head;
}
Lp* Deletelist(Lp* head)
{
if (head == NULL)
{
printf("请先初始化在进行其他操作");
return head;
}//判断是否初始化创建链表
Lp* p = head;
Lp* q = head->next;//p后的链结
printf("请输入要插入那个人的姓名+首个成绩:");
char name[16];
int a;
int k = 0;//检验是否找到数据
scanf("%s", name);
scanf("%d", &a);
while (p->next != NULL)
{
if (strcmp(q->data.name, name) == 0 && q->data.a[0] == a)//这里不能用p->next来因为无法对目标数据进行处理
{
printf("已成功找到要插入数据\n");
p ->next = q->next;
k++;
head->data.length--;
break;
}
else
{
p = p->next;
q = q->next;
}
}
if (k == 0)
{
printf("未找到数据\n");
}
return head;
}
Lp* Deletefirstlist(Lp* head)
{
if (head == NULL)
{
printf("请先初始化在进行其他操作");
return head;
}//判断是否初始化创建链表
Lp* p = head;//用来跳过首个有数据的链结
Lp* q = head->next->next;//注意这里不在是开辟空间啦,这是有数据的链结后的链结
p->next = q;
head->data.length--;
return head;
}
Lp* Deletemenu(Lp* head)
{
void Outputlist(Lp * head);//声明
int a = 0;
printf("***************************\n");
printf("1,删除首位\t2删除某个人数据后面\t3退出\t4输出\n");
while (a != 888)
{
printf("请输入你要选择删除的功能:");
scanf("%d", &a);
switch (a)
{
case 1:head = Deletefirstlist(head); break;
case 2:head = Deletelist(head); break;
case 3: a = 888;//退出循环条件
break;
case 4:Outputlist(head); break;
default:printf("请输入1—4的数据"); break;
}
}
return head;
}
Lp* Chooselist(Lp* head)
{
if (head == NULL)
{
printf("请初始化在进行其他功能!");
return head;
}
Lp* p = head->next;
printf("请输入你要修改学生的姓名+首个成绩:");
char name[16];
scanf("%s", name);
int a;
scanf("%d", &a);
int k = 0;
while (p->next != NULL)
{
if (strcmp(p->data.name, name) == 0 && p->data.a[0] == a)
{
printf("查询到你要修改的数据\n");
printf("请输出要修改的数据的姓名:");
scanf("%s", p->data.name);
printf("请输入学生六科成绩:");
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
scanf("%d", &p->data.a[i]);
}
break;
}
else
{
p = p->next;
}
}
return head;
}
Lp* Sortkaozhilist(Lp* head)
{
printf("按照平均分从小到大的写法且按照拷贝数据域方法进行\n");
Lp* Maxlist(Lp * head);//声明
head = Maxlist(head);
Lp* p = head->next;//控制外循环
Lp* q = head->next;//控制内循环
for (; p->next->next != NULL; p = p->next)
{
for (q=head->next;q->next->next != NULL; q = q->next)//这样写有个不好的,这是是全部进行比较,不是每次少一个但是这样写的好处是不用测量长度!在数据少这样写的快
//这里我想了想设立了一个下标操作!这样写的好处是不用测量长度!
{
if (q->next != NULL || q != NULL)//防止越界
{
if (q->data.average > q->next->data.average)
{
lp t;//作为中间变量进行替换
t = q->data;
q->data = q->next->data;
q->next->data = t;
}
}
}
}
return head;
}
Lp* Sortzhizhenlist(Lp* head)
{
printf("进行的是指针域的改变按照从大到小(适合大数据)\n");
printf("并且是下标法的冒泡排序\n");
printf("请检验下标的数据为:%d\n", head->data.length);
Lp* Maxlist(Lp * head);//声明函数
head = Maxlist(head);
Lp* p = head->next;
Lp* q = head->next->next;//p的后节点
Lp* move=head;//因为p和q指针域发生变化,所以需要用move去遍历
for (int i = 0; i < head->data.length-1; i++)
{
p = head->next;
q = p->next;
move = head;//初始化
for (int j = 0; j < head->data.length - 1 - i; j++)
{
if (p->data.average <q->data.average)
{
p->next = q->next;//把p后面那个节点的指针域给p->next;
q->next = p;//原本时p指向q,现在是q指向p
move->next = q;//找到要移动的位置
}//交换相邻指针域使最少的放在后面;
move = move->next;//这样是每次往后进行相邻比较
p = move->next;
q = p->next;//往后移
}
}
return head;
}
Lp* sortmenu(Lp* head)
{
void Outputlist(Lp * head);//声明
int a = 0;
printf("***************************\n");
printf("1拷贝值排序(适合数据小的)\t2指针域排序(有点不同)\t3退出\t4输出\n");
while (a != 888)
{
printf("请输入你要选择排序的功能:");
scanf("%d", &a);
switch (a)
{
case 1:head = Sortkaozhilist(head); break;
case 2:head = Sortzhizhenlist(head); break;
case 3: a = 888;//退出循环条件
break;
case 4:Outputlist(head); break;
default:printf("请输入1—4的数据"); break;
}
}
return head;
}
Lp* Maxlist(Lp* head)
{
//这里在结构体里加了一个 int average 来进行比较
Lp* p = head->next;//因为头节点数据域为空
while (p->next != NULL)
{
//这里给p->data.average赋初值;
p->data.average = 0;
for (int i = 0; i < sizeof(p->data.a) / sizeof(p->data.a[0]); i++)
{
p->data.average += p->data.a[i];
}
p = p->next;
}
return head;
}
void Maxoutput(Lp* head)
{
Lp* p;
p = head->next;
Lp *max=NULL;
max = p;
while (p->next != NULL)
{
if (p->data.average > max->data.average)
{
max = p;
}
p = p->next;
}
printf("%s:", max->data.name);
for (int i = 0; i < sizeof(p->data.a) / sizeof(p->data.a[0]); i++)
{
printf("%d\n", max->data.a[i]);
}
printf("\n");
}
void Outputlist(Lp* head)
{
Lp* p; p = head->next;//头节点没有数据所以是head->next;
while (p->next != NULL)
{
printf("%s:\t", p->data.name);
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
printf("%d\t", p->data.a[i]);
}
printf("\n");
p = p->next;
}
}
int main()
{
//为了数据的检验方便没有设置及时清屏功能,请见谅
int flag2 = 0;//检验密码登录系统的正确行
/*mima(&flag2);*/
flag2 = 1;
Lp* head = NULL;
if (flag2 != 0)
{
int Tc = 0;//选择菜单的退出
menu();
int choose = 0;//菜单选择的变量
while (Tc == 0)
{
printf("请选择功能:");
scanf("%d", &choose);
switch (choose)
{
case 1:head = Creatlist(head); break;
case 2: head = Insertmenu(head); break;
case 3:head = Deletemenu(head); break;
case 4:head = Chooselist(head); break;
case 6:head = sortmenu(head); break;
case 5:if (head = Maxlist(head))Maxoutput(head);break;
case 7:Outputlist(head); break;
case 8:Tc = 1; break;
case 9:system("cls"); system("pause"); menu(); break;
default:printf("请输入1—9选择功能");
}
}
}
return 0;
}
##学习之作
此为学习上的见解,若有错误或不同理解欢迎大家的批评与改正(第一次写,排版可能有问题,请见谅)文章来源地址https://www.toymoban.com/news/detail-856008.html
到了这里,关于在c语言中使用链表完成学生成绩管理系统(密码登录系统的采纳,加入了隐藏与删除功能,添加了指针域与数据域两种不同的排序)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!