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


在这里插入图片描述


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

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

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

结构示例:

节点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;
}

四、总结

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

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

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

相关推荐

  1. ——双向

    2024-07-14 07:32:01       42 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-14 07:32:01       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-14 07:32:01       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-14 07:32:01       58 阅读
  4. Python语言-面向对象

    2024-07-14 07:32:01       69 阅读

热门阅读

  1. systemverilog的关联数组

    2024-07-14 07:32:01       27 阅读
  2. 最新得物data参数加密分析与响应数据解密

    2024-07-14 07:32:01       19 阅读
  3. JVM OutOfMemoryError异常模拟

    2024-07-14 07:32:01       16 阅读
  4. 2024.7.13刷题记录-牛客小白月赛98(未完)

    2024-07-14 07:32:01       22 阅读
  5. 代码随想录第五十五天打卡

    2024-07-14 07:32:01       24 阅读
  6. 《HarmonyOS应用开发者基础认证》考试题目

    2024-07-14 07:32:01       27 阅读
  7. 每天一个数据分析题(四百二十六)- 总体方差

    2024-07-14 07:32:01       23 阅读
  8. [C++]类与对象

    2024-07-14 07:32:01       20 阅读
  9. 大模型日报 2024-07-13

    2024-07-14 07:32:01       20 阅读
  10. 家校管理系统

    2024-07-14 07:32:01       18 阅读
  11. 使用vllIm部署大语言模型

    2024-07-14 07:32:01       23 阅读