16、创建动态链表并实现插入、删除等功能

16、创建动态链表并实现插入、删除等功能

题目:编程实现下列函数,并将以下所有函数组织在一个 C 程序中:
(1)编写函数 struct student *creat(void),建立一个有 n 名学生数据的头指针为 head 的单向动态链表。链表的结点类型为struct student,如下所示:

 struct student{ 
 		long num;    //学号  
 		int score;   //分数   
		struct student  *next;   //结点指针域
};  

(2)编写函数 struct student *insert(struct student *head),从头指针为 head 的学生链表插入一 个新的学生数据结点。
(3)编写函数 struct student *del(struct student *head, long key), 从头指针为 head 的学生链表中删除 学号为 key 的那个结点。
(4)编写函数 int sum(struct student *head),返回头指针为 head 的学生链表中所有结点分数的和值。
(5)编写函数 void find(struct student *head), 输出头指针为 head 的学生链表中分数最高的学生的学号和分数。
(6)编写函数 void print(struct student *head), 输出头指针为 head 的学生链表中所有结点的内容。

#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;
	}
}
发布了16 篇原创文章 · 获赞 0 · 访问量 295

猜你喜欢

转载自blog.csdn.net/NAU_LHT/article/details/104442701