📅  最后修改于: 2023-12-03 15:06:34.131000             🧑  作者: Mango
双向链表是一种链表数据结构的变种,它与普通链表最大的不同在于每个节点有两个指针,分别指向前面一个节点和后面一个节点。删除双向链表中小于给定值的所有节点需要考虑这种数据结构的特点,下面我们就一步步来讲解。
typedef struct Node {
int val;
struct Node* prev;
struct Node* next;
} Node;
其中,val
表示节点的值,prev
和next
分别表示当前节点的前驱节点和后继节点。
我们可以用下面的函数来创建一个双向链表。
Node* createList(int arr[], int size) {
Node* head = NULL;
Node* tail = NULL;
Node* cur = NULL;
for (int i = 0; i < size; i++) {
cur = (Node*)malloc(sizeof(Node));
cur->val = arr[i];
cur->prev = tail;
cur->next = NULL;
if (tail == NULL) {
head = cur;
tail = cur;
} else {
tail->next = cur;
tail = cur;
}
}
return head;
}
这个函数接收一个整数数组和整数数组的长度作为参数,返回一个双向链表的头节点。
删除小于给定值 value
的节点,可以采用以下思路:
val
小于 value
,则将其从链表中删除。val
大于等于 value
,则继续往下遍历。以下是具体实现:
void removeNodes(Node** head, int value) {
Node* cur = *head;
Node* temp = NULL;
while (cur != NULL) {
if (cur->val < value) { // 删除当前节点
if (cur == *head) { // 删除头节点
*head = cur->next;
if (*head != NULL) {
(*head)->prev = NULL;
}
} else if (cur->next == NULL) { // 删除尾节点
cur->prev->next = NULL;
} else { // 删除中间节点
cur->prev->next = cur->next;
cur->next->prev = cur->prev;
}
temp = cur;
cur = cur->next;
free(temp);
} else { // 继续往下遍历
cur = cur->next;
}
}
}
这个函数接收一个指向双向链表头节点的指针和一个整数 value
作为参数,没有返回值。需要注意的是,由于我们可能需要修改头节点,所以这里传入了指向指针的指针。
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int val;
struct Node* prev;
struct Node* next;
} Node;
Node* createList(int arr[], int size) {
Node* head = NULL;
Node* tail = NULL;
Node* cur = NULL;
for (int i = 0; i < size; i++) {
cur = (Node*)malloc(sizeof(Node));
cur->val = arr[i];
cur->prev = tail;
cur->next = NULL;
if (tail == NULL) {
head = cur;
tail = cur;
} else {
tail->next = cur;
tail = cur;
}
}
return head;
}
void removeNodes(Node** head, int value) {
Node* cur = *head;
Node* temp = NULL;
while (cur != NULL) {
if (cur->val < value) { // 删除当前节点
if (cur == *head) { // 删除头节点
*head = cur->next;
if (*head != NULL) {
(*head)->prev = NULL;
}
} else if (cur->next == NULL) { // 删除尾节点
cur->prev->next = NULL;
} else { // 删除中间节点
cur->prev->next = cur->next;
cur->next->prev = cur->prev;
}
temp = cur;
cur = cur->next;
free(temp);
} else { // 继续往下遍历
cur = cur->next;
}
}
}
void printList(Node* head) {
Node* cur = head;
while (cur != NULL) {
printf("%d ", cur->val);
cur = cur->next;
}
printf("\n");
}
int main() {
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int size = sizeof(arr) / sizeof(arr[0]);
Node* list = createList(arr, size);
int value = 5;
printf("Original list: ");
printList(list);
removeNodes(&list, value);
printf("List after removing nodes less than %d: ", value);
printList(list);
return 0;
}
本文介绍了如何从双向链表中删除小于给定值的所有节点。我们通过遍历双向链表,删除每个小于给定值的节点,最后得到了一个新的双向链表。需要注意的是,这里需要修改指向指针的指针,以便正确地处理头节点。