综合本章例9.9(建立链表的函数creat)、例9.10(输出链表的函数print)和本章习题第7题(删除链表中结点的函数del)、第8题(插入结点的函数insert),再编写一个主函数,先后调用这些函数。用以上5个函数组成一个程序,实现链表的建立、输出、删除和插入,在主函数中指定需要删除和插入的结点的数据。
方法一:
#include <stdio.h>
#include <stdlib.h>
struct Student
{ //声明结构体(双向链表结构体)
int num;
float score;
struct Student *prev;
struct Student *next;
};
struct Student *input(); //声明输入函数
void print(struct Student *stu); //声明输出函数
struct Student *del(struct Student *head, float n); //声明删除函数
struct Student *insert(struct Student **stu, int m, char direc, struct Student *ins); //声明插入函数
int main()
{
struct Student *stud, in, *inser; //定义结构体指针,插入的结构体变量,指向插入结构体变量的指针
float del_score; //定义删除函数的参数(需要删除的对应分数)
int insert_num; //定义要插入的结点学号
char dir; //定义前插后插的方向变量
stud=input(); //调用输入函数
print(stud); //输出全部数据
printf("Please enter delete score: "); //输入要删除的分数
scanf("%f", &del_score);
getchar(); //此项是清除缓冲区内scanf函数输入的最后一个换行符'\n',此后出现该语句作用相同
stud=del(stud, del_score); //调用删除函数
print(stud); //输出结果
printf("Please enter insert student info: "); //输入要插入的学生数据(学号和成绩)
scanf("%d %f", &in.num, &in.score);
getchar();
inser=∈ //结构体变量指针指向in
printf("Please enter insert num: "); //输入要插入哪个学号
scanf("%d", &insert_num);
getchar();
printf("Please enter F or B: "); //输入是要插入学号前还是后,F是前插,B是后插。
scanf("%c", &dir);
getchar();
stud=insert(&stud, insert_num, dir, inser); //调用插入函数
print(stud);
return 0;
}
//输入函数
struct Student *input()
{
struct Student *p1, *p2, *head;
int n=0;
p1=p2=(struct Student*)malloc(sizeof(struct Student));
printf("Please enter No.%d student info: ", n+1);
scanf("%d %f", &p1->num, &p1->score);
getchar();
head=NULL;
while (p1->num!=0)
{
n++;
if (n==1)
{
head=p1;
p1->prev=NULL;
}
else
{
p2->next=p1;
p1->prev=p2;
}
p2=p1;
p1=(struct Student*)malloc(sizeof(struct Student));
printf("Please enter No.%d student info: ", n+1);
scanf("%d %f", &p1->num, &p1->score);
getchar();
}
p2->next=NULL;
return head;
}
//输出函数
void print(struct Student *stu)
{
struct Student *p;
printf("Output Result:\n");
for (p=stu; p!=NULL; p=p->next)
{
printf("%d %.2f\n", p->num, p->score);
}
}
//删除函数
struct Student* del(struct Student *head, float n)
{
struct Student *p, *next;
for (p=head; p!=NULL; p=next)
{
next=p->next;
if (p->score==n)
{
if (p==head)
head=p->next;
if (p->prev!=NULL)
p->prev->next=p->next;
if (p->next!=NULL)
p->next->prev=p->prev;
free(p);
}
}
return head;//改变stu和stud所指向的地址
}
//插入函数
struct Student *insert(struct Student **stu, int m, char direc, struct Student *ins)
{
struct Student *p, *head;
for (p=*stu, head=p; p!=NULL; p=p->next)
{
if (p->num==m)
{
if (direc=='F')
{
if (p==head)//若为第一个结构体数组
{
ins->next=p;
ins->prev=NULL;
head->prev=ins;
head=ins;
}
else
{
ins->prev=p->prev;
p->prev->next=ins;
ins->next=p;
p->prev=ins;
}
}
else if (direc=='B')
{
if (p->next==NULL)//若为最后一个结构体数组
{
p->next=ins;
ins->next=NULL;
ins->prev=p;
}
else
{
ins->next=p->next;
p->next=ins;
ins->prev=p;
}
}
}
}
return head;//返回值为head
}
在VS2019下,需将源文件的scanf做些修改:
#include <stdio.h>
#include <stdlib.h>
struct Student
{ //声明结构体(双向链表结构体)
int num;
float score;
struct Student* prev;
struct Student* next;
};
struct Student* input(); //声明输入函数
void print(struct Student* stu); //声明输出函数
struct Student* del(struct Student* head, float n); //声明删除函数
struct Student* insert(struct Student** stu, int m, char direc, struct Student* ins); //声明插入函数
int main()
{
struct Student* stud, in, * inser; //定义结构体指针,插入的结构体变量,指向插入结构体变量的指针
float del_score; //定义删除函数的参数(需要删除的对应分数)
int insert_num; //定义要插入的结点学号
char dir; //定义前插后插的方向变量
stud = input(); //调用输入函数
print(stud); //输出全部数据
printf("Please enter delete score: "); //输入要删除的分数
scanf_s("%f", &del_score);
getchar(); //此项是清除缓冲区内scanf函数输入的最后一个换行符'\n',此后出现该语句作用相同
stud = del(stud, del_score); //调用删除函数
print(stud); //输出结果
printf("Please enter insert student info: "); //输入要插入的学生数据(学号和成绩)
scanf_s("%d %f", &in.num, &in.score);
getchar();
inser = ∈ //结构体变量指针指向in
printf("Please enter insert num: "); //输入要插入哪个学号
scanf_s("%d", &insert_num);
getchar();
printf("Please enter F or B: "); //输入是要插入学号前还是后,F是前插,B是后插。
scanf_s("%c", &dir, (unsigned int)sizeof(char));
getchar();
stud = insert(&stud, insert_num, dir, inser); //调用插入函数
print(stud);
return 0;
}
//输入函数
struct Student* input()
{
struct Student* p1, * p2, * head;
int n = 0;
p1 = p2 = (struct Student*)malloc(sizeof(struct Student));
printf("Please enter No.%d student info: ", n + 1);
scanf_s("%d %f", &p1->num, &p1->score);
getchar();
head = NULL;
while (p1->num != 0)
{
n++;
if (n == 1)
{
head = p1;
p1->prev = NULL;
}
else
{
p2->next = p1;
p1->prev = p2;
}
p2 = p1;
p1 = (struct Student*)malloc(sizeof(struct Student));
printf("Please enter No.%d student info: ", n + 1);
scanf_s("%d %f", &p1->num, &p1->score);
getchar();
}
p2->next = NULL;
return head;
}
//输出函数
void print(struct Student* stu)
{
struct Student* p;
printf("Output Result:\n");
for (p = stu; p != NULL; p = p->next)
{
printf("%d %.2f\n", p->num, p->score);
}
}
//删除函数
struct Student* del(struct Student* head, float n)
{
struct Student* p, * next;
for (p = head; p != NULL; p = next)
{
next = p->next;
if (p->score == n)
{
if (p == head)
head = p->next;
if (p->prev != NULL)
p->prev->next = p->next;
if (p->next != NULL)
p->next->prev = p->prev;
free(p);
}
}
return head;//改变stu和stud所指向的地址
}
//插入函数
struct Student* insert(struct Student** stu, int m, char direc, struct Student* ins)
{
struct Student* p, * head;
for (p = *stu, head = p; p != NULL; p = p->next)
{
if (p->num == m)
{
if (direc == 'F')
{
if (p == head)//若为第一个结构体数组
{
ins->next = p;
ins->prev = NULL;
head->prev = ins;
head = ins;
}
else
{
ins->prev = p->prev;
p->prev->next = ins;
ins->next = p;
p->prev = ins;
}
}
else if (direc == 'B')
{
if (p->next == NULL)//若为最后一个结构体数组
{
p->next = ins;
ins->next = NULL;
ins->prev = p;
}
else
{
ins->next = p->next;
p->next = ins;
ins->prev = p;
}
}
}
}
return head;//返回值为head
}
方法二:
#include <stdio.h>
#include <stdlib.h>
struct Student
{ //声明结构体(双向链表结构体)
int num;
float score;
struct Student *prev;
struct Student *next;
};
struct Student *input(); //声明输入函数
void print(struct Student *stu); //声明输出函数
void del(struct Student *stu, float n); //声明删除函数
void insert(struct Student **stu, int m, char direc, struct Student *ins); //声明插入函数
int main()
{
struct Student *stud, in, *inser; //定义结构体指针,插入的结构体变量,指向插入结构体变量的指针
float del_score; //定义删除函数的参数(需要删除的对应分数)
int insert_num; //定义要插入的结点学号
char dir; //定义前插后插的方向变量
stud=input(); //调用输入函数
print(stud); //输出全部数据
printf("Please enter delete score: "); //输入要删除的分数
scanf("%f", &del_score);
getchar(); //此项是清除缓冲区内scanf函数输入的最后一个换行符'\n',此后出现该语句作用相同
del(stud, del_score); //调用删除函数
print(stud); //输出结果
printf("Please enter insert student info: "); //输入要插入的学生数据(学号和成绩)
scanf("%d %f", &in.num, &in.score);
getchar();
inser=∈ //结构体变量指针指向in
printf("Please enter insert num: "); //输入要插入哪个学号
scanf("%d", &insert_num);
getchar();
printf("Please enter F or B: "); //输入是要插入学号前还是后,F是前插,B是后插。
scanf("%c", &dir);
getchar();
insert(&stud, insert_num, dir, inser); //调用插入函数
print(stud);
return 0;
}
//输入函数
struct Student *input()
{
struct Student *p1, *p2, *head;
int n=0;
p1=p2=(struct Student*)malloc(sizeof(struct Student));
printf("Please enter No.%d student info: ", n+1);
scanf("%d %f", &p1->num, &p1->score);
getchar();
head=NULL;
while (p1->num!=0)
{
n++;
if (n==1)
{
head=p1;
p1->prev=NULL;
}
else
{
p2->next=p1;
p1->prev=p2;
}
p2=p1;
p1=(struct Student*)malloc(sizeof(struct Student));
printf("Please enter No.%d student info: ", n+1);
scanf("%d %f", &p1->num, &p1->score);
getchar();
}
p2->next=NULL;
return head;
}
//输出函数
void print(struct Student *stu)
{
struct Student *p;
printf("Output Result:\n");
for (p=stu; p!=NULL; p=p->next)
{
printf("%d %.2f\n", p->num, p->score);
}
}
//删除函数
void del(struct Student *stu, float n)
{
struct Student *p, *next;
struct Student *head = stu;
for (p=head; p!=NULL; p=next)
{
next=p->next;
if (p->score==n)
{
if (p==head)
head=p->next;
if (p->prev!=NULL)
p->prev->next=p->next;
if (p->next!=NULL)
p->next->prev=p->prev;
}
}
*stu=*head;//改变sud和stud所指向的内存的内容
}
//插入函数
void insert(struct Student **stu, int m, char direc, struct Student *ins)
{
struct Student *p, *head;
for (p=*stu, head=p; p!=NULL; p=p->next)
{
if (p->num==m)
{
if (direc=='F')
{
if (p==head)//若为第一个结构体数组
{
ins->next=p;
ins->prev=NULL;
head->prev=ins;
head=ins;
}
else
{
ins->prev=p->prev;
p->prev->next=ins;
ins->next=p;
p->prev=ins;
}
}
else if (direc=='B')
{
if (p->next==NULL)//若为最后一个结构体数组
{
p->next=ins;
ins->next=NULL;
ins->prev=p;
}
else
{
ins->next=p->next;
p->next=ins;
ins->prev=p;
}
}
}
}
*stu=head;
}
在VS2019下,需将源文件的scanf做些修改:
#include <stdio.h>
#include <stdlib.h>
struct Student
{ //声明结构体(双向链表结构体)
int num;
float score;
struct Student* prev;
struct Student* next;
};
struct Student* input(); //声明输入函数
void print(struct Student* stu); //声明输出函数
void del(struct Student* stu, float n); //声明删除函数
void insert(struct Student** stu, int m, char direc, struct Student* ins); //声明插入函数
int main()
{
struct Student* stud, in, * inser; //定义结构体指针,插入的结构体变量,指向插入结构体变量的指针
float del_score; //定义删除函数的参数(需要删除的对应分数)
int insert_num; //定义要插入的结点学号
char dir; //定义前插后插的方向变量
stud = input(); //调用输入函数
print(stud); //输出全部数据
printf("Please enter delete score: "); //输入要删除的分数
scanf_s("%f", &del_score);
getchar(); //此项是清除缓冲区内scanf函数输入的最后一个换行符'\n',此后出现该语句作用相同
del(stud, del_score); //调用删除函数
print(stud); //输出结果
printf("Please enter insert student info: "); //输入要插入的学生数据(学号和成绩)
scanf_s("%d %f", &in.num, &in.score);
getchar();
inser = ∈ //结构体变量指针指向in
printf("Please enter insert num: "); //输入要插入哪个学号
scanf_s("%d", &insert_num);
getchar();
printf("Please enter F or B: "); //输入是要插入学号前还是后,F是前插,B是后插。
scanf_s("%c", &dir, (unsigned int)sizeof(char));
getchar();
insert(&stud, insert_num, dir, inser); //调用插入函数
print(stud);
return 0;
}
//输入函数
struct Student* input()
{
struct Student* p1, * p2, * head;
int n = 0;
p1 = p2 = (struct Student*)malloc(sizeof(struct Student));
printf("Please enter No.%d student info: ", n + 1);
scanf_s("%d %f", &p1->num, &p1->score);
getchar();
head = NULL;
while (p1->num != 0)
{
n++;
if (n == 1)
{
head = p1;
p1->prev = NULL;
}
else
{
p2->next = p1;
p1->prev = p2;
}
p2 = p1;
p1 = (struct Student*)malloc(sizeof(struct Student));
printf("Please enter No.%d student info: ", n + 1);
scanf_s("%d %f", &p1->num, &p1->score);
getchar();
}
p2->next = NULL;
return head;
}
//输出函数
void print(struct Student* stu)
{
struct Student* p;
printf("Output Result:\n");
for (p = stu; p != NULL; p = p->next)
{
printf("%d %.2f\n", p->num, p->score);
}
}
//删除函数
void del(struct Student* stu, float n)
{
struct Student* p, * next;
struct Student* head = stu;
for (p = head; p != NULL; p = next)
{
next = p->next;
if (p->score == n)
{
if (p == head)
head = p->next;
if (p->prev != NULL)
p->prev->next = p->next;
if (p->next != NULL)
p->next->prev = p->prev;
}
}
*stu = *head;//改变sud和stud所指向的内存的内容
}
//插入函数
void insert(struct Student** stu, int m, char direc, struct Student* ins)
{
struct Student* p, * head;
for (p = *stu, head = p; p != NULL; p = p->next)
{
if (p->num == m)
{
if (direc == 'F')
{
if (p == head)//若为第一个结构体数组
{
ins->next = p;
ins->prev = NULL;
head->prev = ins;
head = ins;
}
else
{
ins->prev = p->prev;
p->prev->next = ins;
ins->next = p;
p->prev = ins;
}
}
else if (direc == 'B')
{
if (p->next == NULL)//若为最后一个结构体数组
{
p->next = ins;
ins->next = NULL;
ins->prev = p;
}
else
{
ins->next = p->next;
p->next = ins;
ins->prev = p;
}
}
}
}
*stu = head;
}