用C语言完成:有两个链表a,b(静态链表,每个链表包含六个节点,节点数据从键盘输入)每个节点包含学号和姓名。从链表a中删去与链表b中具有相同学号的节点,并输出链表a
时间: 2023-08-31 08:30:28 浏览: 76
### 回答1:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NODE_NUM 6
// 定义链表节点结构体
struct Node {
char id[10];
char name[20];
int next;
};
// 初始化链表
void initList(struct Node list[]) {
for (int i = 0; i < MAX_NODE_NUM; i++) {
printf("请输入第 %d 个节点的信息:\n", i+1);
printf("学号:");
scanf("%s", list[i].id);
printf("姓名:");
scanf("%s", list[i].name);
list[i].next = i+1;
}
list[MAX_NODE_NUM-1].next = -1; // 最后一个节点的 next 值为 -1
}
// 打印链表所有节点信息
void printList(struct Node list[]) {
printf("学号\t姓名\n");
int i = 0;
while (i != -1) {
printf("%s\t%s\n", list[i].id, list[i].name);
i = list[i].next;
}
}
// 从链表 a 中删除与链表 b 中具有相同学号的节点
void deleteSameNode(struct Node a[], struct Node b[]) {
int p = 0;
while (p != -1) {
int q = 0;
while (q != -1) {
if (strcmp(a[p].id, b[q].id) == 0) { // 学号相同
if (q == 0) { // 要删除第一个节点
a[p] = b[0];
b[0] = b[1];
b[1] = b[2];
b[2] = b[3];
b[3] = b[4];
b[4] = b[5];
b[5].next = -1;
}
else { // 要删除非第一个节点
int pre = q-1;
b[pre].next = b[q].next;
b[q].next = -2; // 将要删除的节点的 next 值设置为 -2,便于后续处理
}
}
q = b[q].next; // 遍历链表 b
}
p = a[p].next; // 遍历链表 a
}
// 将链表 b 中 next 值为 -2 的节点删除
int q = 0;
while (q != -1) {
if (b[q].next == -2) {
b[q] = b[q+1];
b[q+1] = b[q+2];
b[q+2] = b[q+3];
b[q+3] = b[q+4];
b[q+4] = b[q+5];
b[5].next = -1;
}
q = b[q].next;
}
}
int main() {
struct Node a[MAX_NODE_NUM], b[MAX_NODE_NUM];
printf("请输入链表 a 的节点信息:\n");
initList(a);
printf("\n链表 a 的所有节点信息如下:\n");
printList(a);
printf("\n请输入链表 b 的节点信息:\n");
initList(b);
printf("\n链表 b 的所有节点信息如下:\n");
printList(b);
deleteSameNode(a, b);
printf("\n从链表 a 中删除与链表 b 中具有相同学号的节点后,链表 a 的所有节点信息如下:\n");
printList(a);
return 0;
}
```
### 回答2:
题目要求从链表a中删除与链表b中具有相同学号的节点,并输出链表a。首先我们需要定义链表节点的结构体,每个节点包含学号和姓名两个字段。
```c
#include<stdio.h>
#include<stdlib.h>
// 定义链表节点结构体
typedef struct Node {
int id; // 学号
char name[20]; // 姓名
struct Node* next; // 指向下一个节点的指针
} Node;
// 从键盘输入学号和姓名
void inputNodeData(Node* node) {
printf("请输入学号:");
scanf("%d", &(node->id));
printf("请输入姓名:");
scanf("%s", node->name);
}
// 创建链表
void createLinkedList(Node* head) {
Node* p = head;
for (int i = 0; i < 6; i++) {
Node* newNode = (Node*)malloc(sizeof(Node));
inputNodeData(newNode);
newNode->next = NULL;
p->next = newNode;
p = p->next;
}
}
// 删除具有相同学号的节点
void deleteSameNodes(Node* headA, Node* headB) {
Node* p = headA->next;
Node* q = headB->next;
Node* pre = headA; // 记录前一个节点
while (p != NULL && q != NULL) {
if (p->id == q->id) { // 如果学号相同,则删除该节点
pre->next = p->next;
free(p);
p = pre->next;
} else if (p->id < q->id) { // 如果链表a的学号较小,则继续遍历链表a
pre = p;
p = p->next;
} else { // 如果链表b的学号较小,则继续遍历链表b
q = q->next;
}
}
}
// 输出链表
void printList(Node* head) {
Node* p = head->next;
while (p != NULL) {
printf("学号:%d 姓名:%s\n", p->id, p->name);
p = p->next;
}
}
int main() {
// 创建链表a和链表b,分别用headA和headB表示头节点
Node* headA = (Node*)malloc(sizeof(Node));
headA->next = NULL;
printf("请输入链表a的数据:\n");
createLinkedList(headA);
Node* headB = (Node*)malloc(sizeof(Node));
headB->next = NULL;
printf("请输入链表b的数据:\n");
createLinkedList(headB);
// 删除链表a中与链表b具有相同学号的节点
deleteSameNodes(headA, headB);
// 输出链表a
printf("链表a的数据为:\n");
printList(headA);
// 释放链表a和链表b的内存
Node* p = headA;
while (p != NULL) {
Node* q = p->next;
free(p);
p = q;
}
p = headB;
while (p != NULL) {
Node* q = p->next;
free(p);
p = q;
}
return 0;
}
```
以上是用C语言完成题目要求的代码。首先我们定义了链表节点`Node`的结构体,包含学号和姓名两个字段,以及指向下一个节点的指针。然后通过`inputNodeData`函数从键盘输入学号和姓名,通过`createLinkedList`函数创建链表a和链表b,分别用`headA`和`headB`表示头节点。接着使用`deleteSameNodes`函数删除链表a中与链表b具有相同学号的节点。最后通过`printList`函数输出链表a的数据,并释放链表a和链表b的内存。
### 回答3:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 6
struct Node {
int id;
char name[20];
struct Node* next;
};
struct Node* createLinkedList() {
struct Node* head = NULL;
struct Node* temp = NULL;
struct Node* p = NULL;
// 创建链表
for (int i = 0; i < MAX_SIZE; i++) {
temp = (struct Node*)malloc(sizeof(struct Node));
if (temp == NULL) {
printf("内存分配失败\n");
exit(1);
}
printf("请输入第%d个节点的学号和姓名:", i + 1);
scanf("%d %s", &(temp->id), temp->name);
temp->next = NULL;
if (head == NULL) {
head = temp;
} else {
p = head;
while (p->next != NULL) {
p = p->next;
}
p->next = temp;
}
}
return head;
}
void deleteNodes(struct Node* listA, struct Node* listB) {
struct Node* p = listA;
struct Node* q = listB;
while (q != NULL) {
struct Node* temp = q;
q = q->next;
p = listA;
struct Node* prev = p;
while (p != NULL) {
if (p->id == temp->id) {
if (p == listA) {
listA = p->next;
} else {
prev->next = p->next;
}
free(p);
break;
}
prev = p;
p = p->next;
}
}
}
void printLinkedList(struct Node* head) {
struct Node* p = head;
while (p != NULL) {
printf("学号:%d 姓名:%s\n", p->id, p->name);
p = p->next;
}
}
int main() {
struct Node* listA = createLinkedList();
struct Node* listB = createLinkedList();
printf("链表A:\n");
printLinkedList(listA);
deleteNodes(listA, listB);
printf("删除与链表B中具有相同学号的节点后的链表A:\n");
printLinkedList(listA);
return 0;
}
```
在该程序中,我们首先定义了一个结构体`Node`表示链表的节点,包含了学号和姓名两个数据成员,以及一个指向下一个节点的指针。然后通过`createLinkedList`函数分别创建了链表A和链表B。在创建链表的过程中,通过`malloc`函数动态分配内存来存储节点,并从键盘输入节点的学号和姓名。接下来,通过`deleteNodes`函数遍历链表B中的每个节点,然后在链表A中找到具有相同学号的节点并删除。最后,通过`printLinkedList`函数输出链表A的内容。
通过编译并运行这段代码,我们可以在控制台输入链表A和链表B的元素,并输出删除相同学号节点后的链表A。
阅读全文