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

一、基本概念

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

二、节点定义

在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");
}
相关推荐
承渊政道17 分钟前
【动态规划算法】(完全背包问题从状态定义到空间优化)
数据结构·c++·学习·算法·leetcode·动态规划·哈希算法
玩转单片机与嵌入式20 分钟前
学习嵌入式AI(TInyML),只需掌握这点python基础即可!
人工智能·python·学习
爱写代码的倒霉蛋20 分钟前
2023年天梯赛L1-8
数据结构·算法
ErizJ30 分钟前
Linux|学习笔记
linux·笔记·学习
相醉为友32 分钟前
040 Linux/裸机/RTOS 项目开发的跨平台兼容性——C语言静态接口抽象底层原理分析
linux·c语言·mcu
大数据三康36 分钟前
Java字符统计:从输入到输出的完整解析
java·学习·循环结构
952361 小时前
SpringAOP
java·后端·学习·spring
上弦月-编程1 小时前
C语言指针超详细教程——从入门到精通(面向初学者)
java·数据结构·算法
莫等闲-2 小时前
代码随想录一刷记录Day44——leetcode1143.最长公共子序列 53. 最大子序和
数据结构·c++·算法·leetcode·动态规划
不灭锦鲤2 小时前
网络安全学习第101天
学习