数据结构 C++双向链表

双向链表

节点类型

template <typename T>
class Node
{
public:
    Node(T data) : _data(data), prev(nullptr), next(nullptr) {}

public:
    T _data;
    Node *prev;
    Node *next;
};

定义类

template <typename T>
class DoublyLinkedList
{
public:
    DoublyLinkedList() : head(nullptr), tail(nullptr), length(0) {}
    ~DoublyLinkedList()
    {
        Clear();
    }

    DoublyLinkedList(const &) = delete;
    operator=(const &) = delete;

    void insertAtHead(T data);           // 在头部插入节点
    void insertAtTail(T data);           // 在尾部插入节点
    void insertPosNode(int pos, T data); // 在指定位置插入
    void deleteAtHead();                 // 删除头部节点
    void deleteAtTail();                 // 删除尾部节点
    void deleteAtPosNode(int pos);       // 删除指定位置节点

    int getSize();
    bool isEmpty();
    void Clear();

    void printForward() const;
    void printBackWard() const;

public:
    Node<T> *head;
    Node<T> *tail;
    int length;
};

1.在头部插入

template <typename T>
void DoublyLinkedList<T>::insertAtHead(T data)
{
    Node<T> *newNode = new Node<T>(data);
    if (head == nullptr)
    {
        head = tail = newNode;
    }
    else
    {
        newNode->next = head;
        head->prev = newNode;
        head = newNode;
    }
    length++;
}

2.在尾部插入

template <typename T>
void DoublyLinkedList<T>::insertAtTail(T data)
{
    Node<T> *newNode = new Node<T>(data);
    if (tail == nullptr)
    {
        head = tail = newNode;
    }
    else
    {
        tail->next = newNode;
        newNode->prev = tail;
        tail = newNode;
    }
    length++;
}

3.在指定位置插入

// 在指定位置插入
template <typename T>
inline void DoublyLinkedList<T>::insertPosNode(int pos, T data)
{
    if (pos < 0 || pos > length)
    {
        std::cout << "invaild postion" << std::endl;
        return;
    }

    if (pos == 0)
    {
        insertAtHead(data);
        return;
    }

    if (pos == length)
    {
        insertAtTail(data);
        return;
    }

    Node<T> *current = head;
    for (int i = 0; i < pos - 1; i++)
    {
        current = current->next;
    }
    Node<T> *newNode = new Node<T>(data);
    newNode->next = current->next;
    newNode->prev = current;
    current->next->prev = newNode;
    current->next = newNode;
    length++;
}

4.头节点删除

// 删除头部节点
template <typename T>
inline void DoublyLinkedList<T>::deleteAtHead()
{
    if (head == nullptr)
        return;
    Node<T> *temp = head;
    if (head == tail)
    {
        head = tail = nullptr;
    }
    else
    {
        head = head->next;
        head->prev = nullptr;
    }
    delete temp;
    length--;
}

5.尾节点删除

// 删除尾部节点
template <typename T>
inline void DoublyLinkedList<T>::deleteAtTail()
{
    if (tail == nullptr)
        return;
    Node<T> *temp = tail;
    if (tail == head)
    {
        tail = head = nullptr;
    }
    else
    {
        tail = tail->prev;
        tail->next = nullptr;
    }
    delete temp;
    length--;
}

6.在指定位置删除

// 删除指定位置节点
template <typename T>
inline void DoublyLinkedList<T>::deleteAtPosNode(int pos)
{
    if (pos < 0 || pos >= length)
    {
        std::cout << "invaild pos" << std::endl;
        return;
    }
    if (pos == 0)
    {
        deleteAtHead();
        return;
    }

    if (pos == length - 1)
    {
        deleteAtTail();
        return;
    }

    Node<T> *current = head;
    for (int i = 0; i < pos; ++i)
    {
        current = current->next;
    }

    current->prev->next = current->next;
    current->next->prev = current->prev;
    delete current;
    length--;
}

7.清除链表

// 清除链表
template <typename T>
inline void DoublyLinkedList<T>::Clear()
{
    while (head != nullptr)
    {
        Node<T> *temp = head;
        head = head->next;
        delete temp;
    }
    tail = nullptr;
    length = 0;
}

完整代码

#ifndef DoublyLinkedList_H
#define DoublyLinkedList_H

#include <iostream>

template <typename T>
class Node
{
public:
    Node(T data) : _data(data), prev(nullptr), next(nullptr) {}

public:
    T _data;
    Node *prev;
    Node *next;
};

template <typename T>
class DoublyLinkedList
{
public:
    DoublyLinkedList() : head(nullptr), tail(nullptr), length(0) {}
    ~DoublyLinkedList()
    {
        Clear();
    }

    DoublyLinkedList(const &) = delete;
    operator=(const &) = delete;

    void insertAtHead(T data);           // 在头部插入节点
    void insertAtTail(T data);           // 在尾部插入节点
    void insertPosNode(int pos, T data); // 在指定位置插入
    void deleteAtHead();                 // 删除头部节点
    void deleteAtTail();                 // 删除尾部节点
    void deleteAtPosNode(int pos);       // 删除指定位置节点

    int getSize();
    bool isEmpty();
    void Clear();

    void printForward() const;
    void printBackWard() const;

public:
    Node<T> *head;
    Node<T> *tail;
    int length;
};

// 在头部插入
template <typename T>
void DoublyLinkedList<T>::insertAtHead(T data)
{
    Node<T> *newNode = new Node<T>(data);
    if (head == nullptr)
    {
        head = tail = newNode;
    }
    else
    {
        newNode->next = head;
        head->prev = newNode;
        head = newNode;
    }
    length++;
}

// 在尾部插入
template <typename T>
void DoublyLinkedList<T>::insertAtTail(T data)
{
    Node<T> *newNode = new Node<T>(data);
    if (tail == nullptr)
    {
        head = tail = newNode;
    }
    else
    {
        tail->next = newNode;
        newNode->prev = tail;
        tail = newNode;
    }
    length++;
}

// 在指定位置插入
template <typename T>
inline void DoublyLinkedList<T>::insertPosNode(int pos, T data)
{
    if (pos < 0 || pos > length)
    {
        std::cout << "invaild postion" << std::endl;
        return;
    }

    if (pos == 0)
    {
        insertAtHead(data);
        return;
    }

    if (pos == length)
    {
        insertAtTail(data);
        return;
    }

    Node<T> *current = head;
    for (int i = 0; i < pos - 1; i++)
    {
        current = current->next;
    }
    Node<T> *newNode = new Node<T>(data);
    newNode->next = current->next;
    newNode->prev = current;
    current->next->prev = newNode;
    current->next = newNode;
    length++;
}

// 删除头部节点
template <typename T>
inline void DoublyLinkedList<T>::deleteAtHead()
{
    if (head == nullptr)
        return;
    Node<T> *temp = head;
    if (head == tail)
    {
        head = tail = nullptr;
    }
    else
    {
        head = head->next;
        head->prev = nullptr;
    }
    delete temp;
    length--;
}

// 删除尾部节点
template <typename T>
inline void DoublyLinkedList<T>::deleteAtTail()
{
    if (tail == nullptr)
        return;
    Node<T> *temp = tail;
    if (tail == head)
    {
        tail = head = nullptr;
    }
    else
    {
        tail = tail->prev;
        tail->next = nullptr;
    }
    delete temp;
    length--;
}

// 删除指定位置节点
template <typename T>
inline void DoublyLinkedList<T>::deleteAtPosNode(int pos)
{
    if (pos < 0 || pos >= length)
    {
        std::cout << "invaild pos" << std::endl;
        return;
    }
    if (pos == 0)
    {
        deleteAtHead();
        return;
    }

    if (pos == length - 1)
    {
        deleteAtTail();
        return;
    }

    Node<T> *current = head;
    for (int i = 0; i < pos; ++i)
    {
        current = current->next;
    }

    current->prev->next = current->next;
    current->next->prev = current->prev;
    delete current;
    length--;
}

// 获取链表大小
template <typename T>
inline int DoublyLinkedList<T>::getSize()
{
    return length;
}

// 判断链表是否为空
template <typename T>
inline bool DoublyLinkedList<T>::isEmpty()
{
    return length == 0;
}

// 清除链表
template <typename T>
inline void DoublyLinkedList<T>::Clear()
{
    while (head != nullptr)
    {
        Node<T> *temp = head;
        head = head->next;
        delete temp;
    }
    tail = nullptr;
    length = 0;
}

// 正向打印链表
template <typename T>
inline void DoublyLinkedList<T>::printForward() const
{
    Node<T> *current = head;
    std::cout << "head->";
    while (current != nullptr)
    {
        std::cout << current->_data;
        if (current->next)
            std::cout << "->";
        current = current->next;
    }
    std::cout << "->nullptr" << std::endl;
}

// 反向打印链表
template <typename T>
inline void DoublyLinkedList<T>::printBackWard() const
{
    Node<T> *current = tail;
    std::cout << "tail->";
    while (current != nullptr)
    {
        std::cout << current->_data;
        if (current->prev)
            std::cout << "->";
        current = current->prev;
    }
    std::cout << "->nullptr" << std::endl;
}

#endif

#include <iostream>
#include "DoublyLinkedList.hpp"

int main(int argc, char const *argv[])
{
    DoublyLinkedList<int> list;

    // 测试 insertAtHead
    std::cout << "Insert at head: 3, 2, 1" << std::endl;
    list.insertAtHead(3);
    list.insertAtHead(2);
    list.insertAtHead(1);
    list.printForward();  // 期望输出: head->1->2->3->nullptr
    list.printBackWard(); // 期望输出: tail->3->2->1->nullptr

    // 测试 insertAtTail
    std::cout << "\nInsert at tail: 4, 5" << std::endl;
    list.insertAtTail(4);
    list.insertAtTail(5);
    list.printForward(); // head->1->2->3->4->5->nullptr

    // 测试 insertPosNode
    std::cout << "\nInsert at position 2: value 99" << std::endl;
    list.insertPosNode(2, 99);
    list.printForward(); // head->1->2->99->3->4->5->nullptr

    // 测试 deleteAtHead
    std::cout << "\nDelete at head" << std::endl;
    list.deleteAtHead();
    list.printForward(); // head->2->99->3->4->5->nullptr

    // 测试 deleteAtTail
    std::cout << "\nDelete at tail" << std::endl;
    list.deleteAtTail();
    list.printForward(); // head->2->99->3->4->nullptr

    // 测试 deleteAtPosNode
    std::cout << "\nDelete at position 1" << std::endl;
    list.deleteAtPosNode(1);
    list.printForward(); // head->2->3->4->nullptr

    // 测试 getSize 和 isEmpty
    std::cout << "\nSize: " << list.getSize() << std::endl;                    // 期望输出: 4
    std::cout << "Is empty? " << (list.isEmpty() ? "Yes" : "No") << std::endl; // No

    // 测试 Clear
    std::cout << "\nClear list" << std::endl;
    list.Clear();
    std::cout << "Size after clear: " << list.getSize() << std::endl;              // 0
    std::cout << "Is empty now? " << (list.isEmpty() ? "Yes" : "No") << std::endl; // Yes
    return 0;
}
posted @ 2025-07-17 18:54  杰西卡若  阅读(18)  评论(0)    收藏  举报