【问题标题】:How to append an element to the end of a linked list?如何将元素附加到链表的末尾?
【发布时间】:2012-09-12 10:18:40
【问题描述】:

我已尝试寻找答案,但似乎找不到任何与我相符的内容。我正在为学校做一个模板链接列表,我得到了一个错误的世界。但我现在只想要一个帮助。我应该将一个元素附加到链表的末尾,但我们得到:

append(ListNode)

起初,我想:“好吧,创建一个新节点,然后在后面插入......”但我读了一遍,我必须创建另一个函数,将两个链表连接在一起。所以我想我必须在链接列表中附加一个已经制作的元素。这样,当我进行连接时,我可以使用我的附加来附加两者。或者至少……这只是我的想法……

所以一开始,我是这样做的:

template<typename NODETYPE> 
bool List<NODETYPE>::append(NODETYPE &value)
{
    ListNode<NODETYPE> *newPtr = getNewNode(value); //creates new node

    if(isEmpty()) //checks if list is empty
    {
        firstPtr = lastPtr = newPtr;
        return true;
    }
    else //inserts new node at end of list
    {
        ListNode<NODETYPE> *tempPtr = lastPtr;

        tempPtr->nextPtr=newPtr;
        lastPtr = newPtr;
        return true;
    }
}

但由于这仅附加一个新节点,因此我无法使用它。有没有办法附加已经制作的节点?例如:将另一个链表附加到前一个链表?

我的 concat(与我搜索过的其他人不同)只使用一个链表。前面的链表对象调用函数,然后附加一个链表

concat(&List)

所以我很困惑。感谢您的帮助,谢谢!

【问题讨论】:

    标签: c++ list linked-list append element


    【解决方案1】:

    连接列表的确切步骤取决于特定的实现细节。最简单的情况是单链表,在这种情况下,您只需将第二个头链接到旧的尾。如果你有一个尾指针,记得更新它。对于双向链表,您还必须将第二个头部链接回旧尾部。如果您使用的是哨兵节点,请记住也要注意这一点。

    编辑:忽略这一点,我很困惑,并认为您可能正在尝试使用标准列表。

    在 C++ 中,std::list 是一个带有标记节点的双向链表,这使得连接变得不平凡。此外,无论如何,您都不应该弄乱内部结构。如果你想使用标准容器,你需要遵守它的公共 API,否则会发生 Bad Stuff。幸运的是,我确信有一个用于连接的库函数。

    【讨论】:

    • 好吧,我不能使用双向链表,或者库中的其他任何东西,因为我认为我们还没有学到任何东西来帮助我们解决这个问题。一切都是从零开始。但是,主要的连接看起来像这样: Li.concat(Li2); Li2 也是一个对象。 Li 和 Li2 都是整数。不过,这确实是对我的补充。我得到类似的东西: Li2.append(5);我看了一下,我仍然认为我必须创建一个新节点才能附加到末尾。我想我的其他功能让我的大脑过度劳累......我现在对所有事情都感到困惑
    【解决方案2】:

    首先,您需要更改 append 方法的签名,使其传递ListNode* 并附加它,无论它是单个节点还是整个链表。之后,您的代码应如下所示:

    template<typename NODETYPE> 
    bool List<NODETYPE>::append(ListNode<NODETYPE>* newPtr)
    {
        //ListNode<NODETYPE> *newPtr = getNewNode(value); //creates new node
    
        if(isEmpty()) //checks if list is empty
        {
            firstPtr = lastPtr = newPtr;
            return true;
        }
        else //inserts new node at end of list
        {
            ListNode<NODETYPE> *tempPtr = lastPtr;
    
            tempPtr->nextPtr=newPtr;
            lastPtr = newPtr;
            while(lastPtr->nextPtr != NULL)
                lastPtr = lastPtr->nextPtr;
            return true;
        }
    }
    

    我没有编译它,所以可能会有一些错误,但你明白了。

    【讨论】:

    • 这是一个愚蠢的问题,但我的大脑很累=[我如何将它放在标题的原型中?我输入: bool append(ListNode) 并且我得到 ListNode 不是类型.. 嗯(谢谢!)
    • ListNode 必须是在某处定义的某个类或结构。您需要 #include 定义它的那个头文件。
    • 是的,它包含在我的标题中。 #include "ListNode.h" 但它也说原型与类中的任何内容都不匹配而且,我通过将 append(ListNode) 更改为 append(ListNode*) 解决了这个问题,但现在我从'得到错误无效转换int' 到 'ListNode*"
    • @Nelliel:我的建议:拿起一本好的 C++ 书开始学习。从长远来看,这将帮助您自己克服这些问题。至于您现在面临的问题,请查看代码中调用此append 方法的位置,看看您在那里传递了int。将其更改为ListNode
    • 谢谢,我一定会这样做的。我真的需要掌握这个窍门。但是,是的,谢谢。唯一的问题是我无法更改我的主要功能,因为这是我的讲师提供的用于测试代码的功能。如果它不能与他的 cpp 一起运行,那么我们的代码有问题。
    【解决方案3】:

    为了将 list2 连接成一个列表 list1,您必须将 list2 的头部附加到 list1 的最后一个节点并更新 lastPtr,如下所示:

    //apart from checking for basic sanity like empty list and things 
    // suppose argument passed is ListNode list2
            ListNode<NODETYPE> *tempPtr = lastPtr;
    
            tempPtr->nextPtr=list2;
            tempPtr = list2;
            while(tempPtr->next != NULL) {
                  tempPtr = tempPtr->next;
            }
             lastPtr = tempPtr;
    
            return true;
    

    【讨论】:

    • 这听起来有点傻,我有点想通了你给我的那部分,但感谢你为我确认——但是我如何为此设置原型?我以前从来没有提到过一个对象(链表内的链表),而且我几天来一直试图弄清楚这一点。我放了 void List::concat(List) 但我知道那是错误的..有没有特殊的方法可以做到这一点?或者如何在代码中分别引用不同的列表?
    • 要设置原型,应该是这样的: bool List::concat(ListNode *list2) - 你只需将指针传递给链表的头部。
    • 谢谢 :D 嗯,我如何检查第二个列表是否为空?我知道我问了很多 --> 我对不知道这么多感到有点沮丧..
    • 为此,您只需检查 if 语句 if list2==NULL。
    猜你喜欢
    • 2013-12-21
    • 1970-01-01
    • 2020-09-13
    • 2018-04-08
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多