已从数据文件records.txt中读取学生信息,建立了带头结点的学生链表。
(1)编写一个函数 int count(LinkNode* head,int sex); 功能是统计学生链表中性别为sex参数(0为男生,1为女生)的人数并返回该值。
(2)编写一个函数 double getMax(LinkNode* head); 功能是统计学生链表中最高的身高并返回该值。
(3)编写一个函数 void deleX(LinkNode* head, int sex); 功能是删除学生链表中性别为sex参数(0为男生,1为女生)的所有学生。
结构体数组版本见之前的博客:《结构体数组版》
代码如下👇👇👇👇👇👇
#include <stdio.h>
#include <stdlib.h>
/*单链表结点类型*/
typedef struct {
int xh; /*学号*/
float sg; /*身高*/
int sex; /*性别,0为男生,1为女生*/
} datatype;
typedef struct node{
datatype data; /*数据域*/
struct node *next; /*指针域*/
} LinkNode;
/*带表头的单链表的基本运算函数*/
LinkNode* initList();/*置一个空表(带头结点)*/
void createList_1(LinkNode* head);/*创建单链表*/
void createList_2(LinkNode* head);/*创建单链表*/
void sort_xh(LinkNode* head);/*单链表按照学号排序*/
void reverse(LinkNode* head);/*单链表倒置*/
void pntList(LinkNode* head);/*打印单链表*/
void save(LinkNode* head,char strname[]);/*保存单链表到文件*/
int count(LinkNode* head,int sex);/*统计学生链表中性别为sex参数(0为男生,1为女生)的人数*/
double getMax(LinkNode* head); /*功能是统计学生链表中最高的身高并返回该值。*/
void deleX(LinkNode* head, int sex); /* 功能是删除学生链表中性别为sex参数(0为男生,1为女生)的所有学生。*/
int main()
{
int num;
LinkNode* first;
first=initList();//置一个带头节点的表
printf("1.头插法建表:\n");
createList_1(first);
pntList(first);
printf("2.尾插法建表:\n");
createList_2(first);
pntList(first);
printf("3.按照学号排序:\n");
sort_xh(first);//按照学号排序
pntList(first);
printf("4.单链表的倒置:\n");
reverse(first);//单链表的倒置
pntList(first);
printf("5.身高最高的人的数值:%.2lf米\n\n",getMax(first)+0.005);//四舍五入到小数点后两位
printf("6.统计学生链表中性别为sex参数(0为男生,1为女生)的人数:\n");
printf("输入0或1:");
scanf("%d",&num);
if(num==0){
printf("男生");
}
else if(num==1){
printf("女生");
}
printf("的个数是%d人\n\n",count(first,num));
printf("7.删除学生链表中性别为sex参数(0为男生,1为女生)的所有学生。\n");
printf("输入0或1:");
scanf("%d",&num);
deleX(first,num);
printf("删除完毕!打印当前链表:\n");
pntList(first);
return 0;
}
/*置一个空表*/
LinkNode* initList()
{ LinkNode* p;
p=( LinkNode*)malloc(sizeof(LinkNode));
p->next=NULL;
return p;
}
/*创建单链表方法1*/
void createList_1(LinkNode* head)
{ FILE *fp;
datatype stu;
LinkNode* p;
if((fp=fopen("D:\\records.txt","r"))==NULL)
{ printf("can not open read file !");
exit(1) ;
}
while(!feof(fp))
{ fscanf(fp,"%d%f%d",&stu.xh,&stu.sg,&stu.sex);
p=( LinkNode*)malloc(sizeof(LinkNode));
p->data=stu;
p->next=head->next;//头插法
head->next=p;
}
fclose(fp);
}
/*创建单链表方法2*/
void createList_2(LinkNode* head)
{ FILE *fp;
datatype stu;
LinkNode* p, *rear;
if((fp=fopen("D:\\records.txt","r"))==NULL)
{ printf("can not open read file !");
exit(1) ;
}
rear=head;
while(!feof(fp))
{ fscanf(fp,"%d%f%d",&stu.xh, &stu.sg, &stu.sex);
p=( LinkNode*)malloc(sizeof(LinkNode));
p->data = stu;
p->next=NULL;
rear->next=p;
rear=p;//尾插法
}
fclose(fp);
}
/*单链表排序*/
void sort_xh(LinkNode* head)
{
LinkNode* q, *p, *u;
p=head->next;
head->next=NULL;/*利用原表头结点建新的空表*/
while(p)
{ q=p; /*q为被插入的结点*/
p=p->next;/*用p记录后继结点*/
/*遍历新链表查找插入位置*/
u=head;
while(u->next!=NULL)/*查找插入位置*/
{ if(u->next->data.xh > q->data.xh)
break;
u=u->next;
}
/*插入在u结点的后面*/
q->next=u->next;
u->next=q;
}
}
int count(LinkNode* head,int sex){/* 统计学生链表中性别为sex参数(0为男生,1为女生)的人数 */
LinkNode* p;
p=head->next;
int num=0;
while(p){
if(p->data.sex==sex){
num++;
}
p=p->next;
}
return num;
}
double getMax(LinkNode* head){ /* 功能是统计学生链表中最高的身高并返回该值。*/
LinkNode *p;
p=head->next;
double temp = p->data.sg;
while(p){
if(p->data.sg>temp){
temp = p->data.sg;
}
p=p->next;
}
return temp;
}
/*单链表倒置*/
void reverse(LinkNode* head)
{ LinkNode* p, *r;
p=head->next;
head->next=NULL;
while(p)
{ r=p;
p=p->next;
/*r指向结点头插到链表*/
r->next=head->next;
head->next=r;
}
}
void deleX(LinkNode* head, int sex){ //删除操作
LinkNode* p = head->next;
LinkNode* pre = head;
while(p){
if(p->data.sex == sex){
pre->next = p->next;
delete(p);
p = pre->next;
}
else{
pre = p;
p = p->next;
}
}
}
/*输出单链表*/
void pntList(LinkNode* head)
{ LinkNode* p;
p=head->next;
while (p!=NULL)
{printf("%2d: %.2f %d\n",p->data.xh,p->data.sg,p->data .sex);
p=p->next;
}
printf("\n");
}
/*保存单链表到文件*/
void save(LinkNode* head, char strname[])
{ FILE *fp;
LinkNode* p;
if((fp=fopen(strname,"w"))==NULL)
{ printf("can not open write file !");
exit(1) ;
}
p=head->next;
while(p!=NULL)
{ fprintf(fp,"%2d %5.2f %2d\n",p->data.xh,p->data.sg,p->data.sex);
p=p->next;
}
fclose(fp);
}
具体展示图片如下:
图片存放修改的位置:👇👇👇👇
为什么用“双斜杠”而非“单斜杠”的原因:
在一般的程序语言中都存在一种字符,即“转义字符”,C语言中的’\‘是一个转义字符,所以如果在路径名中采用单斜杠,编译器就会认为这是一个转义字符,而不是真正的’\‘字符,进而出现打开文件失败的错误。那么解决这个问题就显得顺理成章,既然’\‘是转义字符,我们就采用双斜杠的形式"\",这样在编译器看来,转义字符’\‘将’\‘解释为’\’。