16、ダイナミックリストインサートを作成して実装するには、削除、など
タイトル:次の関数をプログラミングすると、以下の機能のすべては、Cプログラムで構成されています:
機能構造体の学生の(1)準備*レコード生成(無効)、データ先頭ポインタnは学生の確立が一方向の動的なリストに向かいます。次のように、リストのノードタイプstruct学生のリンク:
struct student{
long num; //学号
int score; //分数
struct student *next; //结点指针域
};
(2)*挿入(構造体の学生*機能構造体の学生の書き込みヘッド)、 ヘッドポインタは、連結リストの学生のノード頭部のための新しい生徒データを挿入されています。
(3)は、関数構造体の学生*デル(構造体の学生*書き込みヘッド、長いキー)を、 学生は学校の頭を削除するためのヘッドポインタリストは、キーのノードの数です。
(4)関数int和(構造体の学生*ヘッド)を書く 、 リストの先頭ポインタを返し、すべてのノードの先頭学生の値が得点。
(5)機能を無効のfind(構造体学生*ヘッド)書く 、 学生の学生数の最高得点と生徒のスコアとリストの頭の中で先頭ポインタの出力を。
関数ボイドプリント(構造体学生*ヘッド)の(6)の調製は 、 ヘッド・ポインタは、すべてのノードの内容の生徒リストの出力のヘッドです。
#include<stdio.h>
#include<stdlib.h>
struct student{
long num;
int score;
struct student *next;
};
#define LEN sizeof(struct student) //LEN为结构体类型的存储大小 (define前要有#)
int n=0; //n为链表结点个数
struct student *creat(void);
struct student *insert(struct student *head);
struct student *del(struct student *head, long key);
int sum(struct student *head);
void find(struct student *head);
void print(struct student *head);
int main(){
struct student *head, *p1, *p2;
//学号与成绩输入“0 0”表示链表创建完成或插入结束或删除结束
printf("请按学号大小由小到大输入数据创建链表:\n");
head=creat();
printf("请输入插入结点的学号与成绩:\n");
head=insert(head);
long key;
printf("请输入要删除的结点的学号:\n");//(/与\要注意)
scanf("%d", &key);
head=del(head, key);
printf("所有分数的和值为:%d\n",sum(head));
//最高分的学号与成绩
find(head);
//输出链表全部内容
print(head);
return 0;
}
struct student *creat(void){ //创建链表的详细解释在C语言书P314
struct student *head, *p1, *p2; //当结点数(n)大于1时,p2为相邻两结点的前一个结点,而p1为相邻两结点的后一个结点
head=NULL; //初始时没有结点,故令head为NULL
p2=p1=(struct student*)malloc(LEN); //(p2=)p1=...的括号内容不能少,因为若一开始就输入0 0(即没有结点),执行p2->next= NULL需要p2有初始指向
scanf("%ld %d", &p1->num, &p1->score);//(少了取地址符编译不会报错,但运行程序时会出错)
while(p1->num != 0){ //注意最后要输入0 0才能结束循环
n++;
if(n==1) head=p1;
else p2->next = p1;
p2=p1;
p1=(struct student*)malloc(LEN);
scanf("%ld %d",&p1->num, &p1->score);
}
p2->next=NULL;
return head;
}
struct student *insert(struct student *head){
struct student *p1, *p2, *input;
p1=head;
input=(struct student*)malloc(LEN);
scanf("%ld %d", &input->num, &input->score);
if(head->num > input->num){
input->next = head; //插入到链表的表首之前
head=input;
}else{
while(p1 != NULL){
//因不同学生的学号不可能相同,故不必考虑p1->next == input->next的情况
if(p1->num < input->num){
p2=p1;
p1=p2->next;
}else{
p2->next = input; //插入到链表之中
input->next = p1;
break; //该break很关键,不可少,否则p1不会再移动,该while循环陷入死局不断重复执行else语句
}
}
}
if(p1 == NULL){
p1->next = input; //插入到链表的表尾之后
input->next = NULL;
}
return head;
}
struct student *del(struct student *head, long key){
struct student *p1, *p2;
p1=head;
if(head->num == key){
head=head->next;
n--;
}else{
while(p1!=NULL){
if(p1->num == key){
p2->next = p1->next;
n--;
break;
}else{
p2=p1;
p1=p2->next;
}
}
}
return head;
}
int sum(struct student *head){
struct student *p = head;
int s=0;
while(p != NULL){
s += p->score;
p=p->next;
}
return s;
}
void find(struct student *head){
struct student *p1, *p2;
p1=p2=head;
while(p1 != NULL){
//假设只有一个最高分
if(p2->score < p1->score){
p2=p1;
}
p1=p1->next;
}
printf("最高分为%d,该学生学号为%ld\n", p2->score, p2->num);
}
void print(struct student *head){
struct student *p1 = head;
printf("所有学生的学号与成绩为:\n");
while(p1 != NULL){
printf("%ld %d\n", p1->num, p1->score);
p1=p1->next;
}
}