C语言实现两个单向链表相减
时间: 2024-05-07 11:21:42 浏览: 11
假设我们有两个单向链表A和B,它们分别表示两个集合。现在我们要求出集合A与集合B的差集,也就是只在A中出现而不在B中出现的元素。
我们可以遍历链表A,对于每个节点,判断它是否在链表B中出现过。如果出现过,则将该节点从链表A中删除。最后返回链表A即可。
下面是C语言实现的代码:
```
#include <stdio.h>
#include <stdlib.h>
// 定义节点结构体
typedef struct node {
int data;
struct node* next;
} Node;
// 创建新节点
Node* createNode(int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
// 添加节点到链表末尾
void append(Node** headRef, int data) {
Node* newNode = createNode(data);
if (*headRef == NULL) {
*headRef = newNode;
return;
}
Node* tail = *headRef;
while (tail->next != NULL) {
tail = tail->next;
}
tail->next = newNode;
}
// 从链表中删除给定节点
void deleteNode(Node** headRef, Node* nodeToDelete) {
if (*headRef == NULL) {
return;
}
if (*headRef == nodeToDelete) {
*headRef = nodeToDelete->next;
free(nodeToDelete);
return;
}
Node* prev = *headRef;
while (prev->next != NULL && prev->next != nodeToDelete) {
prev = prev->next;
}
if (prev->next == NULL) {
return;
}
prev->next = nodeToDelete->next;
free(nodeToDelete);
}
// 从链表A中删除在B中出现过的节点
void subtract(Node** headA, Node* headB) {
Node* currA = *headA;
while (currA != NULL) {
Node* currB = headB;
while (currB != NULL && currB->data != currA->data) {
currB = currB->next;
}
if (currB != NULL) {
deleteNode(headA, currA);
currA = *headA;
} else {
currA = currA->next;
}
}
}
// 打印链表
void printList(Node* head) {
Node* curr = head;
while (curr != NULL) {
printf("%d ", curr->data);
curr = curr->next;
}
printf("\n");
}
int main() {
// 创建链表A
Node* headA = NULL;
append(&headA, 1);
append(&headA, 2);
append(&headA, 3);
append(&headA, 4);
append(&headA, 5);
// 创建链表B
Node* headB = NULL;
append(&headB, 3);
append(&headB, 4);
// 求差集
subtract(&headA, headB);
// 打印结果
printList(headA);
return 0;
}
```
上述代码中,我们定义了一个节点结构体,包含一个整型数据和一个指向下一个节点的指针。我们还定义了一些操作链表的函数,如创建新节点、添加节点到链表末尾、删除节点等。最后,我们在主函数中创建了两个链表A和B,然后调用subtract函数求它们的差集,最后打印结果。