现有一串已按分数高低记录好的成绩, 现在要求你在不打乱原来顺序的基础上 插入一部分数据、删除一部分数据,并输出。

本文介绍了一种使用链表进行数据管理的方法,具体应用为在已排序的成绩列表中插入和删除数据,同时保持原有顺序不变。文章详细展示了如何在C语言中实现这一过程,包括节点的创建、连接、数据的插入与删除,以及最终的输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


现有一串已按分数高低记录好的成绩,
现在要求你在不打乱原来顺序的基础上

插入一部分数据、删除一部分数据,并输出。(用链表操作)

输入
输入分3部分:

第一部分为已排序好的成绩,#结束;

第二部分为要增加的成绩,#结束:

第三部分为要删除的成绩,#结束;

输出
输出修改后的成绩

样例输入
LI 95
WANG 90
SUN 85
ZHAO 80
QIAN 70
#
ZHAN 85
JIN 60
#
QIAN
#
样例输出
LI 95
WANG 90
SUN 85
ZHAN 85
ZHAO 80
JIN 60
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
	struct stu
	{
		char name[20];
		int score;
		struct stu *next;
    } *head = NULL,
      *pnow, /* 新增节点的指针. /欲删除的节点指针*/
      *p,  /* 母链表的当前位置的指针 */
        /* 它是独立于链表之外的工作人员般的存在,通过它来访问(操作/修改)他所指的结构体元素的内容, */
      *pre; /* 保存前一个节点的地址(外地址) */

    char buf[20]; /* 数据缓冲区 ,当需要读入的数据比较多样,考虑先放入缓冲区再解析会比较灵活.
                    buf里面可能存放的内容有两类:1.名字/2.'#' (而分数不会进去的(scanf(%s遇到空格结束读入.))) */

	int size_stu = sizeof(struct stu);
	/* 原来的母链表 头部. */

	/* 新增节点的指针. */
	pnow = (struct stu *)malloc(size_stu);
	/* 初始化头部和尾部得指针. */
	p = head = pnow;
	/* 读入第一行数据 并写入到母链表的表头元素中去*/
	scanf("%s %d", &pnow->name, &pnow->score);

	/* 第二行起需要分析读入到缓冲区里的内容 */
	while (scanf("%s", &buf) != EOF)
	{
		if (buf[0] == '#') /*到头了, 结束该母链表的读入 */
		{
			break;
		}
		else
		{
			/* 处理(建立下一个元素 )包括申请节点,连接节点内地址,更新(工作者指针的指向关系)(节点外地址操作)*/
			pnow = (struct stu *)malloc(size_stu);
			/* 连接并更新节点里的指针 */
			p->next = pnow; /* 连接到下一个元素 (采用上一个连接到当前,而非当前连接到下一个)(修改p所指节点的内地址.)*/
			p = pnow;		/* 更新节点里的指针 (将当前节点的外地址赋给p*/
			/* 数据写入到当前. */
			strcpy(pnow->name, buf);
			scanf("%d", &pnow->score);
		}
	}
	p->next = NULL;

	/* 处理增加的items,仍然采取一个一个节点的申请,连接 */
	while (scanf("%s", &buf) != EOF)
	{
		if (buf[0] == '#')
		{
			break;
		}
		else
		{
			pnow = (struct stu *)malloc(size_stu);
			strcpy(pnow->name, buf);
			scanf("%d", &pnow->score);

			p = head->next; /* 保存母链表的首节点的内地址.(第二个节点的地址(如果有的话)) */

			pnow->next = NULL; /* 当前接节点默认独立 */
			/* 比较大小(都从母表头比起.),再合适的位置插入节点. */
			if (pnow->score > head->score) /* 接到头部去 */
			{
				pnow->next = head;
				head = pnow; /* 更新指向头部指针head */
			}
			else
			{
				/* p = head->next; */
				pre = head;
				/*    p->score 原链表第二个节点里的分数. 
				pre,和 p 是母链表中一前一后的关系.
				<= 表示新节点尽量靠后.*/
				while (p != NULL && pnow->score <= p->score) /* 如果仍然小于等于,继续后移. */
				{
					pre = p;
					p = p->next; /* 统称指向下一个节点. */
				}
				pnow->next = p;	  /* 为了防止链表断了,应该从后往前作连接工作. */
				pre->next = pnow; //被赋新值的同时就断开了旧有的链接
			}
		}
	}
	/* 匹配姓名,删除节点. */
	while (scanf("%s", &buf) != EOF)
	{
		if (buf[0] == '#')
			break;
		else
		{
			if (!strcmp(head->name, buf)) /* 匹配成功. */
			{
				p = head;
				head = head->next; /*丢弃旧头部 */
			}
			else
			{
				p = head->next; /* p母链表的当前位置的指针 */
				pre = head;
				/* 当前节点不是最后一个同时 里面的名字不匹配 */
				while (p != NULL && strcmp(p->name, buf) != 0)
				{
					/* p,pre各自指向自己的下一个节点. */
					p = p->next;
					pre = pre->next;
				}
				pre->next = p->next;
				p->next = NULL;
			}
			free(p);
		}
	}
	/* 打印内容. */
	p = head;
	for (; p != NULL;)
	{
		printf("%s %d\n", p->name, p->score);
		p = p->next;
	}
	/* while (p != NULL)
	{
		printf("%s %d\n", p->name, p->score);
		p = p->next;
	} */
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cxxu1375

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值