假设在长度大于 1 的单循环链表中,既无头结点也无头指针。s 为指向某个结点的指针,试编写算法删除结点*s 的直接前驱结点。用C语言编写完整代码
时间: 2024-10-07 15:08:06 浏览: 42
在 C 语言中,由于没有内置的头节点概念,我们需要通过遍历整个链表来找到头节点。以下是删除单循环链表中指定节点 `s` 直接前驱节点的完整代码。我们将链表定义为 `struct Node` 类型,每个节点包含一个整数 `value` 和两个指向相邻节点的指针 `next` 和 `prev`。
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int value;
struct Node* next;
struct Node* prev;
} Node;
// 创建循环链表
Node* createCircularList(int* arr, size_t length) {
Node* node = (Node*)malloc(sizeof(Node));
node->value = arr[0];
for (size_t i = 1; i < length; ++i) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->value = arr[i];
newNode->next = node;
newNode->prev = node->prev;
if (node->prev != NULL)
node->prev->next = newNode;
else
node = newNode; // 链表只有一个节点时,设置head为自身
node = newNode;
}
node->next = node; // 关闭环形链表
return node;
}
// 删除前驱节点
void deletePredecessor(Node** head, Node* s) {
if (*head == NULL || s->next == *head) return; // 空链表或删除第一个节点
Node* current = *head;
while (current->next != s) {
current = current->next;
}
current->prev->next = s->next;
if (s->next == *head) *head = current->prev; // 如果删除了第一个节点,更新头节点
}
// 测试用例
int main() {
int arr[] = {1, 2, 3, 4, 5};
size_t length = sizeof(arr) / sizeof(arr[0]);
Node* head = createCircularList(arr, length);
int target;
printf("Enter a number to find and delete its direct predecessor: ");
scanf("%d", &target);
Node* s = findNode(head, target); // 假定你有findNode函数用于查找目标节点
if (s != NULL) deletePredecessor(&head, s);
// 打印删除操作后的链表,注意这里的打印需要手动递归遍历,因为没有头节点
printf("\nAfter deletion: ");
printCircularList(head);
free(head);
return 0;
}
// 辅助函数:递归打印链表
void printCircularList(Node* node) {
printf("%d ", node->value);
printCircularList(node->next);
}
// 辅助函数:查找节点
Node* findNode(Node* head, int target) {
Node* current = head;
do {
if (current->value == target) return current;
current = current->next;
} while (current != head);
return NULL; // 如果未找到目标,返回NULL
}
```
阅读全文