当前位置: 首页 > article >正文

线性表-链式描述(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;
};


http://www.kler.cn/a/418787.html

相关文章:

  • 「Mac畅玩鸿蒙与硬件35」UI互动应用篇12 - 简易日历
  • electron-vite_14窗口默认全屏铺满
  • Oracle数据恢复—Oracle数据库sysaux文件损坏的数据恢复案例
  • 【Maven】依赖冲突如何解决?
  • 蓝桥杯——递归
  • 开展网络安全成熟度评估:业务分析师的工具和技术
  • 【联表查询】.NET开源 ORM 框架 SqlSugar 系列
  • 【C语言】扫雷游戏(一)
  • 火山引擎VeDI在AI+BI领域的演进与实践
  • Web开发基础学习——理解React组件中的根节点
  • 【计网不挂科】计算机网络——<34道经典简述题>特训
  • Vue.js 深入探索:自定义指令与插件开发
  • vscode远程连接ssh
  • React前端进阶面试(七)
  • 将面具贴到人脸上的过程
  • 【Axure高保真原型】视频列表播放器_横向翻页效果
  • PHP和GD库如何给图片添加反色效果
  • 如何在Solana链上开发Dapp?RPC节点的要求
  • 硬菜3道+馒头
  • 婚纱摄影管理系统|Java|SSM|VUE| 前后端分离
  • 自然语言处理基础概念
  • 给ThinkPHP添加接口Trace
  • jQuery九宫格抽奖,php处理抽奖信息
  • 如何解决服务器扫描出的ASP木马问题
  • C 运算符优先级
  • 李永平:以科技创新为引擎,驱动中国国际未来产业研究院不断前行