本题目要求实现在学生信息单链表的指定位置删除数据,并遍历单链表的算法。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[10]; // 姓名
int score; // 分数
}DataType; // 学生信息
typedef struct {
DataType stu;
struct LNode* link;
}LNode, * PNode, * LinkList;
// 初始化单链表,head为单链表头指针
int InitLinkList(LinkList* head)
{
*head = (LinkList)malloc(sizeof(LNode)); // 申请内存空间,生成头结点
if (!head)
{
printf("初始化链表错误!\n");
return 0;
}
(*head)->link = NULL; // 头结点的指针域为空
return 1;
}
// h为指向单链表的指针,pos为插入位置,从1开始,x为待插入数据元素
int LinkListInsert(LinkList h, int pos, DataType x) // h为指向单链表的指针,pos为插入位置,x为待插入数据元素
{
PNode q;
PNode p = h;
int i = 0; // 计数器
while (p && i < pos - 1) // 指针后移,寻找待插入结点的前驱
{
p = p->link; // 指针后移
i++; // 计数器加一
}
if (!p || i > pos - 1) // 检查插入位置是否在链表中
{
printf("插入位置不合法!\n");
return 0;
}
q = (PNode)malloc(sizeof(LNode)); // 生成新的结点
if (!q) // 检查新结点是否生成
{
printf("不能生成新结点\n");
return 0;
}
strcpy(q->stu.name, x.name); // 将待插入元素存入q结点的data域
q->stu.score = x.score;
q->link = p->link; // 使q结点的指针域指向p结点的后继
p->link = q; // 使p结点的指针指向q结点
return 1;
}
// h为指向单向链表的指针,pos为删除位置,item用于返回被删除结点的前驱
int LinkListDelete(LinkList h, int pos, DataType* item)
{
PNode p = h, q;
int i = 0;
while (p->link && i < pos - 1) // 寻找被删结点的前驱
{
p = p->link;
i++;
}
if (!p->link || i > pos - 1) // 检查待删除元素的位置是否在链表内
{
printf("删除位置不合法!\n");
return 0;
}
q = p->link; // 删除
___________;
*item = q->stu; // 返回被
___________; // 释放被删除结点
return 1;
}
// 遍历单链表
void TraverseLinkList(LinkList h) // h为指向单链表的指针
{
PNode p = h->link;
while (p)
{
printf("%s,%d\n",___________); // 注意中英文标点符号
p = p->link;
}
printf("\n");
}
int main()
{
LinkList L;
int i, pos = 1;
DataType x;
DataType a[4] = { {"Tom",90},{"Lily",87},{"May",92},{"Lucy",78} };
______________; // 初始化单链表
for (i = 0; i < 4; i++)
{
LinkListInsert(L, pos++, a[i]);
}
scanf("%d", &pos);
LinkListDelete(____________);
TraverseLinkList(L);
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------
解答:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[10]; // 姓名
int score; // 分数
}DataType; // 学生信息
typedef struct {
DataType stu;
struct LNode* link;
}LNode, * PNode, * LinkList;
// 初始化单链表,head为单链表头指针
int InitLinkList(LinkList* head)
{
*head = (LinkList)malloc(sizeof(LNode)); // 申请内存空间,生成头结点
if (!head)
{
printf("初始化链表错误!\n");
return 0;
}
(*head)->link = NULL; // 头结点的指针域为空
return 1;
}
// h为指向单链表的指针,pos为插入位置,从1开始,x为待插入数据元素
int LinkListInsert(LinkList h, int pos, DataType x) // h为指向单链表的指针,pos为插入位置,x为待插入数据元素
{
PNode q;
PNode p = h;
int i = 0; // 计数器
while (p && i < pos - 1) // 指针后移,寻找待插入结点的前驱
{
p = p->link; // 指针后移
i++; // 计数器加一
}
if (!p || i > pos - 1) // 检查插入位置是否在链表中
{
printf("插入位置不合法!\n");
return 0;
}
q = (PNode)malloc(sizeof(LNode)); // 生成新的结点
if (!q) // 检查新结点是否生成
{
printf("不能生成新结点\n");
return 0;
}
strcpy(q->stu.name, x.name); // 将待插入元素存入q结点的data域
q->stu.score = x.score;
q->link = p->link; // 使q结点的指针域指向p结点的后继
p->link = q; // 使p结点的指针指向q结点
return 1;
}
// h为指向单向链表的指针,pos为删除位置,item用于返回被删除结点的前驱
int LinkListDelete(LinkList h, int pos, DataType* item)
{
PNode p = h, q;
int i = 0;
while (p->link && i < pos - 1) // 寻找被删结点的前驱
{
p = p->link;
i++;
}
if (!p->link || i > pos - 1) // 检查待删除元素的位置是否在链表内
{
printf("删除位置不合法!\n");
return 0;
}
q = p->link; // 删除
p->link=q->link; //#1
*item = q->stu; // 返回被
free(q); //#2 // 释放被删除结点
return 1;
}
// 遍历单链表
void TraverseLinkList(LinkList h) // h为指向单链表的指针
{
PNode p = h->link;
while (p)
{
printf("%s,%d\n",p->stu.name,p->stu.score); // 注意中英文标点符号 #3
p = p->link;
}
printf("\n");
}
int main()
{
LinkList L;
int i, pos = 1;
DataType x;
DataType a[4] = { {"Tom",90},{"Lily",87},{"May",92},{"Lucy",78} };
InitLinkList(&L); // 初始化单链表 #4
for (i = 0; i < 4; i++)
{
LinkListInsert(L, pos++, a[i]);
}
scanf("%d", &pos);
LinkListDelete(L,pos,&x); //#5
TraverseLinkList(L);
return 0;
}