数据结构学习记录之链表篇(二)双向循环链表

DoubleLoopLinkedList.hpp

/**
 * 双向循环链表模板类
 * **/

#include <iostream>

/** 节点类模板 **/
template<class T>
class NodeDLoop
{
public:
    T data;
    NodeDLoop<T>* prev;
    NodeDLoop<T>* next;

    NodeDLoop();
    NodeDLoop(T value);
    
};

template<class T>
NodeDLoop<T>::NodeDLoop()
{

}

template<class T>
NodeDLoop<T>::NodeDLoop(T value): data(value), prev(nullptr), next(nullptr)
{

}

/** 链表类模板 **/
template<class T>
class DLLinked
{
private:
    NodeDLoop<T>* first;
    unsigned int num;

public:
    DLLinked();
    DLLinked(const DLLinked<T>& original);
    ~DLLinked();

    bool empty() const;
    void pushBack(T value);
    unsigned int length() const;
    void display() const;
    void destroy();
    void pushFront(T value);
    void popBack();
    void popFront();
    void insert(unsigned int pos, T value);
    void erase(int pos);
    void revise(unsigned int pos, T value);
    NodeDLoop<T>* headNode() const;
    NodeDLoop<T>* last() const;
    NodeDLoop<T>* find(T value);
    NodeDLoop<T>* operator[](unsigned int pos);
    NodeDLoop<T>* at(unsigned int pos);
    DLLinked<T> operator=(const DLLinked<T>& rightHandSide);

};

template<class T>
DLLinked<T> DLLinked<T>::operator=(const DLLinked<T>& rightHandSide)
{
    if (this == &rightHandSide)
    {
        return *this;
    }
    this->destroy();
    NodeDLoop<T>* ptr = rightHandSide.first;
    while (ptr->next != rightHandSide.first)
    {
        ptr = ptr->next;
        pushBack(ptr->data);
    }
    return *this;
}

template<class T>
DLLinked<T>::DLLinked(const DLLinked<T>& original): num(0)
{
    first = new NodeDLoop<T>;
    first->next = first;
    first->prev = first;
    NodeDLoop<T>* ptr = original.first;
    while (ptr->next != original.first)
    {
        ptr = ptr->next;
        pushBack(ptr->data);
    }
}

template<class T>
NodeDLoop<T>* DLLinked<T>::at(unsigned int pos)
{
    if (pos < num)
    {
        unsigned int index = 0;
        NodeDLoop<T>* ptr = first;
        while (index < pos)
        {
            ptr = ptr->next;
            ++index;
        }
        return ptr->next;
    }
    std::cerr << "index out of range!" << std::endl;
    exit(1);
}

template<class T>
NodeDLoop<T>* DLLinked<T>::operator[](unsigned int pos)
{
    if (pos < num)
    {
        unsigned int index = 0;
        NodeDLoop<T>* ptr = first;
        while (index < pos)
        {
            ptr = ptr->next;
            ++index;
        }
        return ptr->next;
    }
    std::cerr << "index out of range!" << std::endl;
    exit(1);
}

template<class T>
NodeDLoop<T>* DLLinked<T>::find(T value)
{
    if (!empty())
    {
        NodeDLoop<T>* ptr = first;
        bool isExist = false;
        while (ptr->next != first)
        {
            ptr = ptr->next;
            if (ptr->data == value)
            {
                isExist = true;
                break;
            }
        }
        if (isExist)
        {
            return ptr;
        }
        else
        {
            return nullptr;
        }
    }
    std::cerr << "Linked is empty!" << std::endl;
    return nullptr;
}

template<class T>
void DLLinked<T>::revise(unsigned int pos, T value)
{
    if (pos < num)
    {
        unsigned int index = 0;
        NodeDLoop<T>* ptr = first;
        while (index < pos)
        {
            ptr = ptr->next;
            ++index;
        }
        ptr->next->data = value;
    }
    std::cerr << "index out of range!" << std::endl;
}

template<class T>
NodeDLoop<T>* DLLinked<T>::last() const
{
    return first->prev;
}

template<class T>
NodeDLoop<T>* DLLinked<T>::headNode() const
{
    return first;
}

template<class T>
void DLLinked<T>::erase(int pos)
{
    if (pos < num)
    {
        NodeDLoop<T>* ptr = first;
        unsigned int index = 0;
        while (index < pos)
        {
            ptr = ptr->next;
            ++index;
        }
        std::cout << "ptr->data: " << ptr->data << std::endl;
        NodeDLoop<T>* ptrNext = ptr->next;
        ptr->next = ptrNext->next;
        ptrNext->next->prev = ptr;
        delete ptrNext;
        --num;
        return;
    }
    std::cerr << "index out of range!" << std::endl;
}

template<class T>
void DLLinked<T>::insert(unsigned int pos, T value)
{
    if (!empty())
    {
        if (pos < num)
        {
            unsigned int index = 0;
            NodeDLoop<T>* ptr = first;
            if (index < pos)
            {
                ptr = ptr->next;
                ++index;
            }
            NodeDLoop<T>* newPtr = new NodeDLoop<T>(value);
            newPtr->prev = ptr;
            newPtr->next = ptr->next;
            ptr->next = newPtr;
            ++num;
            return;
        }
        else
        {
            NodeDLoop<T>* ptr = first;
            while (ptr->next != first)
            {
                ptr = ptr->next;
            }
            NodeDLoop<T>* newPtr = new NodeDLoop<T>(value);
            ptr->next = newPtr;
            newPtr->prev = ptr->next;
            newPtr->next = first;
            ++num;
            return;
        }
    }
    NodeDLoop<T>* newPtr = new NodeDLoop<T>(value);
    first->next = newPtr;
    newPtr->prev = first;
    first->prev = newPtr;
    newPtr->next = first;
    ++num;
}

template<class T>
void DLLinked<T>::popFront()
{
    if (!empty())
    {
        NodeDLoop<T>* ptr = first->next;
        first->next = ptr->next;
        ptr->next->prev = first;
        delete ptr;
        --num;
        return;
    }
}

template<class T>
void DLLinked<T>::pushFront(T value)
{
    if (!empty())
    {
        NodeDLoop<T>* newPtr = new NodeDLoop<T>(value);
        newPtr->next = first->next;
        newPtr->prev = first;
        first->next = newPtr;
        ++num;
        return;
    }
    NodeDLoop<T>* newPtr = new NodeDLoop<T>(value);
    first->next = newPtr;
    newPtr->prev = first;
    first->prev = newPtr;
    newPtr->next = first;
    ++num;
}

template<class T>
void DLLinked<T>::popBack()
{
    if (!empty())
    {
        NodeDLoop<T>* ptr = first;
        while (ptr->next->next != first)
        {
            ptr = ptr->next;
        }
        delete ptr->next;
        ptr->next = first;
        first->prev = ptr;
        --num;
    }
}

template<class T>
void DLLinked<T>::destroy()
{
    NodeDLoop<T>* ptr = first;
    NodeDLoop<T>* nex = first;
    while (ptr->next != first)
    {
        ptr = ptr->next;
        delete nex;
        nex = ptr;
        num--;
    }
    first->next = first;
    first->prev = first;
}

template<class T>
void DLLinked<T>::display() const
{
    NodeDLoop<T>* ptr = first;
    while (ptr->next != first)
    {
        ptr = ptr->next;
        std::cout << ptr->data << " ";
    }
    std::cout << std::endl;
    
}

template<class T>
unsigned int DLLinked<T>::length() const
{
    return num;
}

template<class T>
void DLLinked<T>::pushBack(T value)
{
    if (!empty())
    {
        NodeDLoop<T>* ptr = first;
        while (ptr->next != first)
        {
            ptr = ptr->next;
        }
        NodeDLoop<T>* newPtr = new NodeDLoop<T>(value);
        ptr->next = newPtr;
        newPtr->prev = ptr->next;
        newPtr->next = first;
        ++num;
        return;
    }
    NodeDLoop<T>* newPtr = new NodeDLoop<T>(value);
    first->next = newPtr;
    newPtr->prev = first;
    newPtr->next = first;
    first->prev = newPtr;
    ++num;
}

template<class T>
bool DLLinked<T>::empty() const
{
    return (first->next == first && first->prev == first);
}

template<class T>
DLLinked<T>::DLLinked(): num(0)
{
    first = new NodeDLoop<T>;
    first->prev = first;
    first->next = first;
}

template<class T>
DLLinked<T>::~DLLinked()
{
    destroy();
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值