双向链表(C语言实现)

双向链表是一种链式数据结构,它允许我们在链表中向前和向后遍历。每个节点都包含指向前一个节点和后一个节点的指针。相比单向链表,双向链表可以更快地进行向前和向后的遍历,但它的实现也更加复杂。

code:

#include <stdio.h>
#include <stdlib.h>

struct Node {
    int data;
    struct Node* next;
    struct Node* prev;
};

void insertAtBeginning(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 insertAfter(struct Node* prev_node, int new_data) {
    if (prev_node == NULL) {
        printf("The given previous node cannot be NULL");
        return;
    }

    struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
    new_node->data = new_data;
    new_node->next = prev_node->next;
    prev_node->next = new_node;
    new_node->prev = prev_node;

    if (new_node->next != NULL)
        new_node->next->prev = new_node;
}

void insertAtEnd(struct Node** head_ref, int new_data) {
    struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
    struct Node* last = *head_ref;

    new_node->data = new_data;
    new_node->next = NULL;

    if (*head_ref == NULL) {
        new_node->prev = NULL;
        *head_ref = new_node;
        return;
    }

    while (last->next != NULL)
        last = last->next;

    last->next = new_node;
    new_node->prev = last;
}

void deleteNode(struct Node** head_ref, struct Node* del) {
    if (*head_ref == NULL || del == NULL)
        return;

    if (*head_ref == del)
        *head_ref = del->next;

    if (del->next != NULL)
        del->next->prev = del->prev;

    if (del->prev != NULL)
        del->prev->next = del->next;

    free(del);
}

void printList(struct Node* node) {
    struct Node* last;
    printf("\nTraversal in forward direction \n");
    while (node != NULL) {
        printf(" %d ", node->data);
        last = node;
        node = node->next;
    }

    printf("\nTraversal in reverse direction \n");
    while (last != NULL) {
        printf(" %d ", last->data);
        last = last->prev;
    }
}

int main() {
    struct Node* head = NULL;

    insertAtEnd(&head, 6);
    insertAtBeginning(&head, 7);
    insertAtBeginning(&head, 1);
    insertAtEnd(&head, 4);
    insertAfter(head->next, 8);

    printf("Created DLL is: ");
    printList(head);

    deleteNode(&head, head);
    deleteNode(&head, head->next);
    deleteNode(&head, head->next);

    printf("\nDLL after deletion is: ");
    printList(head);

    return 0;
}
双向链表常见的应用案例有:
  1. 实现LRU缓存淘汰算法:维护一个双向链表,每次访问数据时,将数据节点移到链表头部,当缓存满时,淘汰链表尾部节点。

  2. 实现文本编辑器:文本编辑器需要支持插入、删除、移动光标等操作,使用双向链表可以方便地实现。

  3. 实现浏览器前进后退功能:浏览器中的历史记录可以使用双向链表维护,每次访问一个新的页面时,将其加入链表尾部,当需要前进或后退时,将指针移动到前一个或后一个节点。

  4. 实现音乐播放器:音乐播放器需要支持播放列表的增删改查操作,使用双向链表可以方便地实现。

  5. 实现哈希表:哈希表中每个桶内的元素可以使用双向链表来实现,方便插入、删除、查找等操作。

  6. 数据库中的双向链表:数据库中的双向链表是实现事务和并发控制的一种常见数据结构,可以在读写过程中有效地管理数据。

  7. 图形用户界面 (GUI):GUI 中的窗口、菜单和工具栏等通常使用双向链表来管理它们的布局和交互。

  8. 浏览器历史记录:浏览器历史记录通常使用双向链表来记录用户的浏览历史,使用户可以通过点击“前进”和“后退”按钮来返回之前访问过的网页。

  9. 编辑器中的文本编辑器:文本编辑器使用双向链表来存储文本文档中的字符,并且可以将其作为光标的位置。

  10. 内存管理:内存管理系统中,双向链表用于跟踪空闲内存块和已分配的内存块,并且在内存分配和释放时改变指针。
    … …

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值