嵌入式第二十六篇——数据结构双向链表

一、基本概念

双向链表是一种常见的数据结构,每个节点包含两个指针,分别指向前驱节点和后继节点。与单向链表相比,双向链表可以从任意节点向前或向后遍历,操作更灵活。

二、节点定义

在C语言中,双向链表的节点通常定义为结构体,包含数据域和两个指针域:

c 复制代码
typedef struct Node {
    int data;           // 数据域
    struct Node *prev;  // 指向前驱节点
    struct Node *next;  // 指向后继节点
} Node;

三、创建双向链表

初始化一个双向链表通常需要创建头节点,并将指针初始化为NULL

c 复制代码
Node* createList() {
    Node *head = (Node*)malloc(sizeof(Node));
    if (head == NULL) {
        printf("内存分配失败\n");
        exit(1);
    }
    head->prev = NULL;
    head->next = NULL;
    return head;
}

四、插入节点

双向链表的插入操作分为头部插入、尾部插入和指定位置插入。

1、头部插入:

c 复制代码
void insertAtHead(Node *head, int data) {
    Node *newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->prev = NULL;
    newNode->next = head->next;

    if (head->next != NULL) {
        head->next->prev = newNode;
    }
    head->next = newNode;
}

2、尾部插入:

c 复制代码
void insertAtTail(Node *head, int data) {
    Node *newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;

    Node *current = head;
    while (current->next != NULL) {
        current = current->next;
    }

    current->next = newNode;
    newNode->prev = current;
}

五、删除节点

删除操作需要调整前驱和后继节点的指针:

c 复制代码
void deleteNode(Node *head, int data) {
    Node *current = head->next;
    while (current != NULL) {
        if (current->data == data) {
            if (current->prev != NULL) {
                current->prev->next = current->next;
            }
            if (current->next != NULL) {
                current->next->prev = current->prev;
            }
            free(current);
            return;
        }
        current = current->next;
    }
    printf("未找到该节点\n");
}

六、遍历双向链表

双向链表支持正向和反向遍历:

1、正向遍历:

c 复制代码
void traverseForward(Node *head) {
    Node *current = head->next;
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");
}

2、反向遍历:

c 复制代码
void traverseBackward(Node *head) {
    Node *current = head;
    while (current->next != NULL) {
        current = current->next;
    }
    while (current != head) {
        printf("%d ", current->data);
        current = current->prev;
    }
    printf("\n");
}
相关推荐
RuoZoe1 小时前
重塑WPF辉煌?基于DirectX 12的现代.NET UI框架Jalium
c语言
祈安_3 天前
C语言内存函数
c语言·后端
西岸行者5 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
norlan_jame5 天前
C-PHY与D-PHY差异
c语言·开发语言
琢磨先生David5 天前
Day1:基础入门·两数之和(LeetCode 1)
数据结构·算法·leetcode
czy87874755 天前
除了结构体之外,C语言中还有哪些其他方式可以模拟C++的面向对象编程特性
c语言
悠哉悠哉愿意5 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
m0_531237175 天前
C语言-数组练习进阶
c语言·开发语言·算法
qq_454245035 天前
基于组件与行为的树状节点系统
数据结构·c#
超级大福宝5 天前
N皇后问题:经典回溯算法的一些分析
数据结构·c++·算法·leetcode