写3个函数建立链表, 删除结点, 插入结点,输出3名学生的数据记录
#pragma warning(disable : 4996)
#include
#include
#include
#define N 3 //3位学生
#define LEN (sizeof(struct Student))
typedef struct Student
{
long number;
float score;
struct Student* next;
}student;
int main()
{
student* ahead;
student* creat(int n); //创建声明
student* del(student * head, long n); //删除声明
student* insert(student * head, student * new_Node); //插入声明
void print(student * head); //输出声明
void clear(student * head); //释放声明
ahead = creat(N);
print(ahead);
long t;
printf("please enter the student number that needs to be deleted:"); //输入想要删除的学号
scanf("%ld", &t);
printf("\n");
del(ahead, t);
print(ahead);
printf("please enter the student number you want to add:"); //输入想要插入的学号,成绩
student* new_Node;
new_Node = (student*)malloc(LEN);
if (new_Node == NULL)
{
printf("out of memory, the request failed!"); //内存不足,申请失败
exit(-1); //程序异常退出
}
memset(new_Node, 0, LEN);
scanf("%ld %f", &new_Node->number, &new_Node->score);
printf("\n");
ahead = insert(ahead, new_Node);
print(ahead);
return 0;
}
student* creat(int n) //尾插法创建链表
{
int i;
student* head, * node, * end;
head = (student*)malloc(LEN); //给头结点申请空间
if (head == NULL)
{
printf("out of memory, the request failed!"); //内存不足,申请失败
exit(-1); //程序异常退出
}
memset(head, 0, LEN);
end = head; //首尾地址一致,空表
printf("enter data records for 3 students:\n");
for (i = 0; i < n; i++)
{
node = (student*)malloc(LEN); //给普通结点申请空间
if (node == NULL)
{
printf("out of memory, the request failed!"); //内存不足,申请失败
exit(-1); //程序异常退出
}
memset(node, 0, LEN); //清零
end->next = node; //前驱结点的指针域存放着当前结点的地址
end = node; //指向后驱结点
scanf("%ld %f", &node->number, &node->score);
}
end->next = NULL; //尾结点地址为空
return head; //返回第一个结点的地址
}
student* del(student* head,long n) //删除结点
{
student* p;
if (head->next == NULL) //链表有头结点,则头结点的指针域为空就表示链表为空
{
printf("the table is empty!\n"); //空表
return head;
}
else
{
for (; head != NULL; head = head->next) //p不能指向空,所以当p指向尾结点后结束循环
{
if (head->next->number == n) //p的后驱结点中数据域中number的值
{
p = head->next;
head->next = head->next->next; //当前p的指针域存放下下个结点的地址,跳过了p的后驱结点
free(p); //释放p的后驱结点的内存空间
return head; //返回第一个结点的地址
}
else
{
printf("the node could not be found!\n"); //找不到该结点
}
}
}
}
student* insert(student* head, student* new_Node) //插入结点
{
student* p;
for (p = head; head != NULL ; p = p->next) //如果新插入结点的学生号 > 某个结点的学生号,并且不能是尾结点,因为尾结点后面不能插入结点
{
if (new_Node->number > p->number)
{
new_Node->next = p->next; //插入结点的指针域存放p的后驱结点
p->next = new_Node; //p的指针域存放新插入结点的地址
return head; //返回第一个结点的地址
}
}
}
void print(student* head) //输出链表
{
student* p;
printf("Now, the data of these students are :\n");
for (p = head->next; p != NULL; p = p->next)
{
printf("%5ld\t%5.2f\n", p->number, p->score);
}
}
void clear(student* head) //释放内存
{
student* p;
while (head != NULL) //循环条件:链表不为空,当链表结点内存释放完,链表为空时,循环结束
{
p = head; //p指向头结点
head = head->next; //head指向下一个结点
free(p);
p = NULL;
}
}
```)
###### 运行结果及报错内容
```c
enter data records for 3 students:
10101 90.0
10103 98.0
10105 87.0
Now, the data of these students are :
10101 90.00
10103 98.00
10105 87.00
please enter the student number that needs to be deleted:10103
the node could not be found! //出错
Now, the data of these students are :
10101 90.00
10105 87.00
please enter the student number you want to add:10107 12
Now, the data of these students are :
10107 12.00 //出错,10107应该最下面的
10101 90.00
10105 87.00
警告 C4715 “insert”: 不是所有的控件路径都返回值
警告 C4715 “del”: 不是所有的控件路径都返回值
student* del(student* head,long n) 删除结点函数,student* insert(student* head, student* new_Node) 插入结点函数,两个函数做了修改,改动处见注释,供参考:
#pragma warning(disable : 4996)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 3 //3位学生
#define LEN (sizeof(struct Student))
typedef struct Student
{
long number;
float score;
struct Student* next;
}student;
int main()
{
student* ahead;
student* creat(int n); //创建声明
student* del(student * head, long n); //删除声明
student* insert(student * head, student * new_Node); //插入声明
void print(student * head); //输出声明
void clear(student * head); //释放声明
ahead = creat(N);
print(ahead);
long t;
printf("please enter the student number that needs to be deleted:"); //输入想要删除的学号
scanf("%ld", &t);
printf("\n");
del(ahead, t);
print(ahead);
printf("please enter the student number you want to add:");//输入想要插入的学号,成绩
student* new_Node;
new_Node = (student*)malloc(LEN);
if (new_Node == NULL)
{
printf("out of memory, the request failed!"); //内存不足,申请失败
exit(-1); //程序异常退出
}
memset(new_Node, 0, LEN);
scanf("%ld %f", &new_Node->number, &new_Node->score);
printf("\n");
ahead = insert(ahead, new_Node);
print(ahead);
return 0;
}
student* creat(int n) //尾插法创建链表
{
int i;
student* head, * node, * end;
head = (student*)malloc(LEN); //给头结点申请空间
if (head == NULL)
{
printf("out of memory, the request failed!"); //内存不足,申请失败
exit(-1); //程序异常退出
}
memset(head, 0, LEN);
end = head; //首尾地址一致,空表
printf("enter data records for 3 students:\n");
for (i = 0; i < n; i++)
{
node = (student*)malloc(LEN); //给普通结点申请空间
if (node == NULL)
{
printf("out of memory, the request failed!"); //内存不足,申请失败
exit(-1); //程序异常退出
}
memset(node, 0, LEN); //清零
end->next = node; //前驱结点的指针域存放着当前结点的地址
end = node; //指向后驱结点
scanf("%ld %f", &node->number, &node->score);
}
end->next = NULL; //尾结点地址为空
return head; //返回第一个结点的地址
}
student* del(student* head,long n) //删除结点
{
student* p;
if (head->next == NULL) //链表有头结点,则头结点的指针域为空就表示链表为空
{
printf("the table is empty!\n"); //空表
return head;
}
else
{
for (; head->next != NULL; head = head->next)//p不能指向空,所以当p指向尾结点后结束循环
//for (; head != NULL; head = head->next) 修改
{
if (head->next->number == n) //p的后驱结点中数据域中number的值
{
p = head->next;
head->next = head->next->next; //当前p的指针域存放下下个结点的地址,跳过了p的后驱结点
free(p); //释放p的后驱结点的内存空间
return head; //返回第一个结点的地址
}
} //修改
//else 修改
//{ 修改
if (!head->next) //修改
printf("the node could not be found!\n");//找不到该结点
//} 修改
}
}
student* insert(student* head, student* new_Node) //插入结点
{
student* p;
for (p = head; p->next != NULL ; p = p->next)//如果新插入结点的学生号 > 某个结点的学生号,并且不能是尾结点,因为尾结点后面不能插入结点
//for (p = head; head != NULL ; p = p->next)//修改
{
if (new_Node->number < p->next->number) //修改 if (new_Node->number > p->number)
{
break; //修改
}
} //修改
new_Node->next = p->next;//插入结点的指针域存放p的后驱结点 //修改
p->next = new_Node; //p的指针域存放新插入结点的地址 //修改
return head; //返回第一个结点的地址
}
void print(student* head) //输出链表
{
student* p;
printf("Now, the data of these students are :\n");
for (p = head->next; p != NULL; p = p->next)
{
printf("%5ld\t%5.2f\n", p->number, p->score);
}
}
void clear(student* head) //释放内存
{
student* p;
while (head != NULL) //循环条件:链表不为空,当链表结点内存释放完,链表为空时,循环结束
{
p = head; //p指向头结点
head = head->next; //head指向下一个结点
free(p);
p = NULL;
}
}