C++数据结构——双端链表

本文详细展示了如何使用C++模板类实现双端链表,包括构造、析构、遍历、清空、拷贝、赋值、插入、删除和更新元素等操作。代码涵盖基本功能并附带主函数进行测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主页有其他数据结构内容(持续更新中)

代码:

#include <iostream>
using namespace std;


template<class T>
struct Node
{
    T data;
    Node<T>* next;  //  后继结点
    Node<T>* prior; //  前驱结点

    Node()
    {
        next = nullptr;
        prior = nullptr;
    }
    explicit Node(T temp, Node<T>* link_prior = nullptr, Node<T>* link_next = nullptr)
    {
        data = temp;
        next = link_next;
        prior = link_prior;
    }
};


template<class T>
class DoubleLinkedList
{
    Node<T>* head;
    int count;

public:
    DoubleLinkedList();
    ~DoubleLinkedList();
    int size()const;
    bool empty()const;  //判表空
    void traverse();  //遍历表
    void clear();  //清空表
    DoubleLinkedList(const DoubleLinkedList<T>& item);  //拷贝构造函数
    DoubleLinkedList<T>& operator=(const DoubleLinkedList<T>& item);  //赋值运算符重载
    void insert(int position, const T& temp);  //在指定位置插入元素
    void remove(int position);  //删除指定位置的元素
    void update(int position, const T& temp);  //替换指定位置的元素
};


template<class T>
DoubleLinkedList<T>::DoubleLinkedList() {
    this->head = nullptr;
    this->count = 0;
}


template<class T>
DoubleLinkedList<T>::~DoubleLinkedList() {
    clear();
}


template<class T>
int DoubleLinkedList<T>::size() const {
    return this->count;
}


template<class T>
bool DoubleLinkedList<T>::empty() const {
    return count == 0;
}


template<class T>
void DoubleLinkedList<T>::traverse() {
    Node<T>* p = this->head;
    while (p){
        cout << p->data << "\t";
        p = p->next;
    }
}


template<class T>
void DoubleLinkedList<T>::clear() {
    while (this->head){
        Node<T>* toDelete = this->head;
        this->head = this->head->next;
        delete toDelete;
    }
    this->count = 0;
}


template<class T>
DoubleLinkedList<T>::DoubleLinkedList(const DoubleLinkedList<T> &item) {
    Node<T>* original_node = item.head;
    Node<T>* copy_node;
    if (item.head == nullptr){
        this->head = nullptr;
        this->count = 0;
    }
    else{
        copy_node = this->head = new Node<T>(item.head->data);
        while (original_node->next){
            original_node = original_node->next;
            Node<T>* temp = new Node<T>(original_node->data, copy_node, nullptr);
            copy_node->next = temp;
            copy_node = temp;
        }
        this->count = item.count;
    }
}


template<class T>
DoubleLinkedList<T> &DoubleLinkedList<T>::operator=(const DoubleLinkedList<T> &item) {
    clear();
    Node<T>* original_node = item.head;
    Node<T>* copy_node;
    if (item.head == nullptr){
        this->head = nullptr;
        this->count = 0;
    }
    else{
        copy_node = this->head = new Node<T>(item.head->data);
        while (original_node->next){
            original_node = original_node->next;
            Node<T> temp = new Node<T>(original_node->data, copy_node, nullptr);
            copy_node->next = temp;
            copy_node = copy_node->next;
        }
        this->count = item.count;
    }
    return *this;
}


template<class T>
void DoubleLinkedList<T>::insert(int position, const T &temp) {
    if (position < 0 || position > this->count){
        cout << "插入位置非法" << endl;
    }
    else{
        if (!position){ //  插在头部(0号位置)
            if (!this->head){
                this->head = new Node<T>(temp);
            }
            else{
                Node<T>* toInsert = new Node<T>(temp, nullptr, this->head);
                this->head->prior = toInsert;
                this->head = toInsert;
            }
        }
        else{
            Node<T>* p = this->head;
            for (int i = 0; i < position - 1; ++i) {
                p = p->next;
            }
            Node<T>* toInsert = new Node<T>(temp, p, p->next);
            if (p->next){   //  不是插在尾部
                p->next->prior = toInsert;
            }
            p->next = toInsert;
        }
        this->count++;
    }
}


template<class T>
void DoubleLinkedList<T>::remove(int position) {
    if (this->empty()){
        cout << "当前链表已空,无法继续删除" << endl;
    }
    else{
        if (position < 0 || position > this->count - 1){
            cout << "删除位置非法" << endl;
        }
        else{
            if (!position){
                Node<T>* toDelete = this->head;
                this->head = this->head->next;
                delete toDelete;
            }
            else {
                Node<T>* p = this->head;
                for (int i = 0; i < position - 1; ++i) {
                    p = p->next;
                }
                Node<T>* toDelete = p->next;
                p->next = toDelete->next;
                if (position != this->count - 1){
                    toDelete->next->prior = p;
                }
                delete toDelete;
            }
        }
        this->count--;
    }
}


template<class T>
void DoubleLinkedList<T>::update(int position, const T &temp) {
    if (position < 0 || position > this->count - 1){
        cout << "修改位置非法" << endl;
    }
    else{
        Node<T>* p = this->head;
        for (int i = 0; i < position; ++i) {
            p = p->next;
        }
        p->data = temp;
    }
}


int main(){
    DoubleLinkedList<int> dll;
    for (int i = 0; i < 10; ++i) {
        dll.insert(i, i * i);
    }
    dll.traverse();
    cout << endl;

    dll.remove(0);
    dll.remove(8);
    dll.traverse();
    cout << endl;

    dll.update(0, 100);
    dll.update(7, 200);
    dll.traverse();
    cout << endl;

    DoubleLinkedList<int> copy_1 = dll; //  测试赋值运算符
    cout << "copy_1的内容为:";
    copy_1.traverse();
    cout << endl;
    DoubleLinkedList<int> copy_2 = DoubleLinkedList<int>(dll);  //  测试拷贝构造函数
    cout << "copy_2的内容为:";
    copy_2.traverse();
    cout << endl;

    cout << "双端链表的长度为:" << dll.size() << endl;
    dll.clear();
    cout << "清除后,双端链表的长度为:" << dll.size() << endl;


    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值