双向链表是一种链表数据结构,它与单向链表不同之处在于,每个节点不仅包含指向下一个节点的指针,还包含指向前一个节点的指针。这种结构允许在双向链表中向前和向后遍历节点,提供了更多的灵活性。
以下是双向链表的基本结构:
struct Node {
int data;
struct Node* next;
struct Node* prev;
};
data
:存储节点中的数据。next
:指向下一个节点的指针。prev
:指向前一个节点的指针。
双向链表允许在链表中的任何位置插入或删除节点而无需重新链接整个链表。这是它的一个优点,但相对于单向链表,它需要更多的内存来存储额外的指针。
以下是一个简单的双向链表的示例:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
struct Node* prev;
};
//链表的前端插入新的节点 head_ref是指针的指针,这里存放指针的地址&head
//这里用到指针的指针是因为要用到每个节点地址运算,所有只能传节点的地址进来。
void insertAtFront(struct Node** head_ref, int new_data) {
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
new_node->prev = NULL;
if ((*head_ref) != NULL) {
(*head_ref)->prev = new_node;
}
(*head_ref) = new_node;
}
void printList(struct Node* node) {
while (node != NULL) {
printf("%d ", node->data);
node = node->next; }
printf("\n");
}
int main() {
struct Node* head = NULL;
insertAtFront(&head, 3);
insertAtFront(&head, 7);
insertAtFront(&head, 11);
printf("Forward traversal: ");
printList(head);
return 0;
}
这个示例展示了如何创建一个简单的双向链表,并在链表的前端插入新的节点。虽然只展示了在链表前端插入的操作,但同样可以实现在链表中间或末尾插入、删除节点等操作,而不必遍历整个链表。通过双向链接,可以更方便地进行前向和后向遍历。
需要注意的是,与单向链表相比,双向链表需要更多的内存来存储额外的指针,但在需要频繁进行前向和后向遍历的情况下,它提供了更高的效率和灵活性。