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

现有一串已按分数高低记录好的成绩,
现在要求你在不打乱原来顺序的基础上
插入一部分数据、删除一部分数据,并输出。(用链表操作)
输入
输入分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;
}
posted @   xuchaoxin1375  阅读(7)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示