线性表-链式描述(C++)

链式实现的线性表:

链式实现的线性表,即链表(Linked List),是一种通过节点(Node)的集合来存储数据的线性数据结构。在链表中,每个节点包含两部分:存储数据的域(数据域)和指向下一个节点的指针(指针域)。链表中的节点通过指针相互连接,形成一个序列。

优点
  1. 动态性:链表不需要在创建时指定大小,可以动态地增加或减少节点,非常适合用于需要频繁插入和删除操作的场景。

  2. 内存利用效率高:对于稀疏的数据集,链表可以通过只存储实际存在的元素来节省内存。

  3. 灵活的插入和删除操作:在链表中,插入和删除操作通常只需要修改相邻节点的指针,而不需要移动大量的数据。这使得链表在插入和删除操作上具有较高的效率。

缺点
  1. 访问速度慢:由于链表中的节点是通过指针相互连接的,因此访问链表中的某个元素通常需要从头节点开始遍历整个链表。这使得链表的访问速度相对较慢,特别是在需要频繁访问元素的场景中。

  2. 内存开销大:链表中的每个节点都需要额外的内存来存储指针,这增加了内存的开销。特别是在双向链表中,每个节点需要两个指针,进一步增加了内存的使用。

  3. 指针管理复杂:链表的操作需要频繁地修改指针,这增加了程序的复杂性。如果不小心管理指针,可能会导致内存泄漏、指针悬挂(dangling pointer)或野指针(wild pointer)等问题。

抽象类linearList

template<typename T>
class linearList
{
public:
    virtual ~linearList(){};
    virtual bool empty() const = 0;
    virtual int size() const = 0;
    virtual T& get(const int& theIndex) const = 0;
    virtual int indexOf(const T& theElement) const = 0;
    virtual void erase(const int& theIndex) const = 0;
    virtual void insert(const int& theIndex,const T& theElement) = 0;
    virtual void optput(std::ostream& out) const = 0;
};

 节点类linkNode

template <typename T>
class linkNode
{
    T element;
    linkNode<T> *next;

    linkNode()
    {
        next = nullptr;
    }

    linkNode(const T& element)
    {
        this->elempent = element;
    }

    linkNode(const T& element, linkNode<T>* next)
    {
        this->elempent = element;
        this->next = next;
    }
};

派生类linkList

template<typename T>
class linkList : public linearList<T>
{
public:
    linkList(int initialCapacity = 10);
    linkList(const linkList<T>&);
    ~linkList();

    bool empty() const;
    int size() const;
    T &get(const int &theIndex) const;
    int indexOf(const T &theElement) const;
    void erase(const int &theIndex);
    void insert(const int &theIndex, const T &theElement);
    void optput(ostream &out) const;

    class iterator;
    iterator begin()
    {
        return iterator(firstNode);
    }

    iterator end()
    {
        return iterator(nullptr);
    }
private:
    void checkIndex(const int& theIndex) const;


private:
    linkNode<T>* firstNode;
    int listSize;
};
template<typename T>
linkList<T>::linkList(int initialCapacity)
{
    assert(initialCapacity > 0);
    firstNode = nullptr;
    listSize = 0;
}

template<typename T>
linkList<T>::linkList(const linkList<T> &theList)
{
    listSize = theList.listSize;

    if(listSize == 0)

    {
        firstNode = nullptr;
        return;
    }

    auto sourveNode = theList.firstNode;
    firstNode = new linkNode<T>(sourveNode->element);

    sourveNode = sourveNode->next;

    auto targetNode = firstNode;

    while (sourveNode != nullptr)
    {
        targetNode->next = new linkNode<T>(sourveNode->next);
        targetNode = targetNode->next;
        sourveNode = sourveNode->next;
    }
    targetNode->next = nullptr;
}

template<typename T>
linkList<T>::~linkList()
{
    while (firstNode != nullptr)
    {
        auto nextNode = firstNode->next;
        delete firstNode;
        firstNode = nextNode;
    }
}

template<typename T>
bool linkList<T>::empty() const
{
    return listSize == 0;
}

template<typename T>
int linkList<T>::size() const
{
    return listSize;
}

template<typename T>
T &linkList<T>::get(const int &theIndex) const
{
    checkIndex(theIndex);

    auto currentNode = firstNode;
    for(int i = 0; i < listSize; i++)
    {
        currentNode = currentNode->next;
        return currentNode->element;
    }
}

template<typename T>
int linkList<T>::indexOf(const T &theElement) const
{
    auto currentNode = firstNode;
    int index = 0;
    while(currentNode != nullptr && currentNode->element != theElement)
    {
        currentNode = currentNode->next;
        index++;
    }

    if(currentNode == nullptr)
    {
        return -1;
    }
    else
    {
        return index;
    }
}

template<typename T>
void linkList<T>::erase(const int &theIndex)
{
    checkIndex(theIndex);

    linkNode<T>* deleteNode;
    if(theIndex == 0)
    {
        deleteNode = firstNode;
        firstNode = firstNode->next;
    }
    else
    {
        auto p = firstNode;
        for(int i = 0; i < theIndex - 1; i++)
        {
            p = p->next;
        }


        deleteNode = p->next;
        p->next = p->next->next;
    }
    listSize--;
    delete deleteNode;
}

template<typename T>
void linkList<T>::insert(const int &theIndex, const T &theElement)
{
    assert(theIndex >= 0 && theIndex <= listSize);

    if(theIndex == 0)
    {
        firstNode = new linkNode<T>(theElement,firstNode);

    }
    else
    {
        auto p = firstNode;
        for(int i =0; i < theIndex - 1; i++)
        {
            p = p->next;
            p->next = new linkNode<T>(theElement,p->next);
        }
    }
    listSize++;
}

template<typename T>
void linkList<T>::optput(ostream &out) const
{
    for(auto currentNode = firstNode; currentNode != nullptr; currentNode = currentNode->next)
    {
        out << currentNode->element << " ";
    }
}

template<typename T>
void linkList<T>::checkIndex(const int &theIndex) const
{
    assert(theIndex >= 0 && theIndex < listSize);
}

template<typename T>
ostream& operator<<(ostream& out,const linkList<T>& theLinkList)
{
    theLinkList.optput(out);
    return out;
}

迭代器

template<typename T>
class iterator
{
public:
    typedef bidirectional_iterator_tag iterator_category;
    typedef ptrdiff_t difference_type;

    iterator(linkNode<T>* theNode = nullptr)
    {
        node = theNode;
    }

    T& operator*() const
    {
        return node->element;
    }

    T* operator->() const
    {

        return &node->element;
    }

    iterator& operator++()
    {
        node = node->next;
        return *this;
    }

    iterator operator++(int)
    {
        auto old = *this;
        node = node->next;
        return old;
    }

    bool operator!=(const iterator right) const
    {
        return node != right.node;
    }

    bool operator==(const iterator right) const
    {
        return node == right.node;
    }

protected:
    linkNode<T>* node;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值