模板中的链表

Posted

技术标签:

【中文标题】模板中的链表【英文标题】:Linked list in template 【发布时间】:2015-01-06 09:48:08 【问题描述】:

我正在大学从事一个项目,同时阅读 C++ 课程。我们目前正在使用链接列表,并且也已开始使用模板。不知何故,我无法链接我的列表,换句话说,我的下一个功能将不起作用。我没有得到“分段错误(核心转储)”,因为如果指向不正确,编译中没有抱怨,当我运行程序并将人员添加到列表时也没有抱怨,问题是它没有找不到我添加的下一个元素,它只打印出我的第一个元素。

这是我的元素模板:

template <class T>
class element 
private:
    element <T> * next;
    T name;
public:
    element <T> * get_nxt () 
        return next;
    
    void set_name (string nam) 
        name = nam;
    
    string get_name () 
        return name;
    
    void set_nxt (element <T> * n) 
        next = n;
    
;

所以当我不想链接两个指针时,我使用:

set_nxt(元素 * n);

所以在代码中它看起来像(我想将 ptr2 设置为 ptr1 旁边):

ptr1->set_nxt(ptr2);

因为我稍后想检查我的列表包含多少元素,它只说一个。

这是我用来计数的计数函数:

template < class T >
int lista<T>::count (lista<T> & L) 
    element <T> *curr = LIST;
    int nr = 0;
    while (curr) 
        curr = curr->get_nxt();
        ++nr;
    
    return nr;

问题出在哪里,因为即使我添加了 2 或更多,此函数也会返回 1。

列表是这样声明的:

template < class T >
class lista 
private:
    element <T> * LIST;
public:
    lista () 
        LIST = NULL;
    
    void add(lista<T> & , string, int);
    int count(lista<T> & );
    void print (lista <T> & );
;

我有 LIST 而不是流行的头部。我一直盯着代码看几个小时,但我找不到任何问题。我们之前一直在做没有模板的链表,我认为链接过程对于链表的模板是相同的。

添加元素:

void lista<T>::add (lista<T> & L, string name, int cond) 
    element <T> *curr = LIST, *fill;
    fill = new element <T>;
    curr = new element <T>;
    if (cond == 0) 
        int nr;
        nr = L.count(L);
        if (nr == 0) 
            curr->set_name (name);
            LIST = curr;
        
        else if (nr > 0) 
            int i;
            for (i = 1 ; i < nr ; ++i)
                curr = curr->get_nxt();
            fill->set_name(name);
            curr->set_nxt (fill);
            fill->set_nxt(NULL);
        

忽略 if (cond == 0) 这不是必需的。

【问题讨论】:

确定LIST 指向列表的头部吗?能否请您展示如何创建一个简单的列表(Minimal, Complete, and Verifiable Example)? 我编辑了,添加功能在主帖末尾。 @CNAP I've been staring at the code for what seems hours and I can not find anything wrong 是时候学习如何使用调试器了。您不能编写这样的重要程序,也不能期望使用调试器对其进行调试。盯着代码只能走这么远…… @PaulMcKenzie 好的,谢谢,我会看看! @JoachimPileborg 您想要列表和类的唯一模板还是包含在添加、打印和计数功能中?抱歉,我是这个论坛的新手,第一次发布有关编程的问题,所以不知道具体该怎么做。 【参考方案1】:

你的lista&lt;T&gt;::add函数有几个问题:

首先你分配curr指向LIST,然后直接重新分配给你分配的新节点。

当您将第一个节点添加到列表 (nr == 0) 时,您不会将 next 指针设置为 NULL

当你添加第二个节点时 (nr == 1) curr 不指向第一个节点(因为第一个点)所以你真的什么都没有添加。

由于上一个问题,您根本不会将任何节点添加到列表中,因为除了第一个节点之外的所有节点都将是第二个节点,而您实际上并没有添加它。

如果您在调试器中逐行检查代码,所有这些问题对您来说都是非常清楚的。


如果是我创建 add 函数,它看起来像这样:

void lista<T>::add (lista<T> & L, string name, int cond) 
    if (cond == 0)
        return;

    if (LIST == nullptr) 
        // Adding the first node in the list
        LIST = new element<T>;
        LIST->set_nxtT(nullptr);
        LIST->set_name(name);
     else 
        // First find the last node
        element<T>* last;
        for (last = LIST; last->get_nxt() != nullptr; last = last->get_nxt())
            ;

        // Add a new node
        last->set_nxt(new element<T>);
        last->get_nxt()->set_nxt(nullptr);
        last->get_nxt()->set_name(name);
    

【讨论】:

以上是关于模板中的链表的主要内容,如果未能解决你的问题,请参考以下文章

如何将我自己的链表中的迭代器定义为 Java 中的节点?

从c中的链表中删除名称时出错

如何从java中的链表中删除一个对象?

javascript中的链表结构—从链表中删除元素

从 O(1) 中的链表中删除任何元素 - Java vs C++

标准模板库中的链表(list)