深入解析双向链表与单向链表的区别:示例详解


在这里插入图片描述


链表是一种灵活的数据结构,它通过指针连接一系列节点,实现了动态数组的特性。在众多链表类型中,单向链表和双向链表是最为常见的两种。本文将重点探讨这两种链表的区别,并通过示例进行详细说明。

一、单向链表与双向链表的定义及结构

单向链表
定义:单向链表是链表的一种,每个节点包含数据域和一个指向下一个节点的指针。

结构示例:

节点Node {
    int data; // 数据域
    Node next; // 指针域,指向下一个节点
}

双向链表
定义:双向链表是链表的一种,每个节点包含数据域、一个指向前一个节点的指针和一个指向下一个节点的指针。

结构示例:

节点Node {
    int data; // 数据域
    Node prev; // 指针域,指向前一个节点
    Node next; // 指针域,指向下一个节点
}

二、单向链表与双向链表的区别示例

插入操作

假设要在链表中的某个节点后插入一个新的节点,以下是单向链表和双向链表的插入操作示例。

单向链表插入操作:

// 假设要在节点p后插入新节点newNode
newNode.next = p.next;
p.next = newNode;

双向链表插入操作:

// 假设要在节点p后插入新节点newNode
newNode.prev = p;
newNode.next = p.next;
if (p.next != null) {
    p.next.prev = newNode;
}
p.next = newNode;

从上述示例可以看出,双向链表在插入操作时需要同时维护前驱节点和后继节点的指针,而单向链表只需维护后继节点的指针。

删除操作

假设要删除链表中的某个节点,以下是单向链表和双向链表的删除操作示例。

单向链表删除操作:

// 假设要删除节点p
if (p.prev != null) {
    p.prev.next = p.next;
}

双向链表删除操作:

// 假设要删除节点p
if (p.prev != null) {
    p.prev.next = p.next;
} else {
    // p是头节点,需要更新头节点
    head = p.next;
}
if (p.next != null) {
    p.next.prev = p.prev;
}

从上述示例可以看出,双向链表在删除操作时需要同时维护前驱节点和后继节点的指针,而单向链表只需维护前驱节点的指针。

三、完整示例

以下是双向链表的一个简单示例(C++):

#include <iostream>

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

    Node(int data) : data(data), next(nullptr), prev(nullptr) {}
};

class DoublyLinkedList {
public:
    Node* head;
    Node* tail;

    DoublyLinkedList() : head(nullptr), tail(nullptr) {}

    void insertAtHead(int data) {
        Node* newNode = new Node(data);
        if (head == nullptr) {
            head = tail = newNode;
        } else {
            newNode->next = head;
            head->prev = newNode;
            head = newNode;
        }
    }

    void printList() const {
        Node* temp = head;
        while (temp != nullptr) {
            std::cout << temp->data << " <-> ";
            temp = temp->next;
        }
        std::cout << "NULL" << std::endl;
    }

    ~DoublyLinkedList() {
        Node* current = head;
        while (current != nullptr) {
            Node* next = current->next;
            delete current;
            current = next;
        }
    }
};

int main() {
    DoublyLinkedList list;

    list.insertAtHead(3);
    list.insertAtHead(2);
    list.insertAtHead(1);

    list.printList();

    return 0;
}

在这个示例中,我们创建了一个双向链表,并在链表头部插入新结点。注意,插入操作中需要同时更新新结点的next和prev指针,以及前一个结点的prev指针和后一个结点的next指针。

以下是单向链表的一个简单示例(C++):

#include <iostream>

struct Node {
    int data;
    Node* next;

    Node(int data) : data(data), next(nullptr) {}
};

class LinkedList {
public:
    Node* head;

    LinkedList() : head(nullptr) {}

    void insertAtHead(int data) {
        Node* newNode = new Node(data);
        newNode->next = head;
        head = newNode;
    }

    void printList() const {
        Node* temp = head;
        while (temp != nullptr) {
            std::cout << temp->data << " -> ";
            temp = temp->next;
        }
        std::cout << "NULL" << std::endl;
    }

    ~LinkedList() {
        Node* current = head;
        while (current != nullptr) {
            Node* next = current->next;
            delete current;
            current = next;
        }
    }
};

int main() {
    LinkedList list;

    list.insertAtHead(3);
    ist.insertAtHead(2);
    list.insertAtHead(1);

    list.printList();

    return 0;
}

四、总结

通过以上示例,我们可以总结出单向链表与双向链表以下几个主要区别:

  • 结构差异:双向链表每个节点有两个指针域,分别指向前一个节点和后一个节点;单向链表只有一个指针域,指向下一个节点。
  • 操作差异:双向链表在插入和删除操作时,需要同时维护前驱节点和后继节点的指针;单向链表只需维护一个方向的指针。
  • 功能差异:双向链表可以快速访问前驱节点和后继节点,适用于需要双向遍历的场景;单向链表只能单向遍历,适用于只需单向访问的场景。
  • 空间占用:双向链表由于每个节点有两个指针域,因此占用空间较大;单向链表占用空间较小。
  • 实现复杂度:双向链表实现相对复杂,需要考虑前驱节点和后继节点的指针修改;单向链表实现简单。

在实际应用中,根据具体需求和场景选择合适的链表类型,可以提高程序的性能和效率。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白话Learning

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值