【问题标题】:Adding a node to the end of a linked list将节点添加到链表的末尾
【发布时间】:2014-02-24 00:27:46
【问题描述】:

我一直在尝试将一个项目添加到链接列表的末尾。我想我已经掌握了这个概念,但我在实现代码时遇到了困难。特别是能够遍历链表并找到尾部。这是我到目前为止所拥有的。我已经有一段时间尝试不同的事情了。任何帮助将不胜感激。

##include <iostream>
using namespace std;


class node
{
public:
    int data;
    node *next;
};


class linkedList
{
private:
    node* ptrHead;
    node* ptrTail;

    int size;

public:
    linkedList();  //default constructor
    void display();
    void addFront(int);
    void removeFront();
    void addBack(int);
    void removeBack();
};

//default constructor
linkedList::linkedList(){
    size = 0;
    ptrHead = ptrTail = NULL;
}
//display linked list
void linkedList::display(){
    node* current = ptrHead;

    while (current != NULL) {
        cout << current->data << " "; //display current item
        current = current->next; //move to next item
    }
    cout << size;
}
//add item to front of linked list
void linkedList::addFront(int addData){

    node* n = new node;
    n->next = ptrHead;
    n->data = addData;
    ptrHead = n;

    size++;
}
//remove item from front of linked list
void linkedList::removeFront(){

    node* n = ptrHead;
    ptrHead = ptrHead->next;
    delete n;

    size--;
}

       void linkedList::addBack(int addData){   ////work in progress


        node* n = new node; //create new node
        n->data = addData;  //input data
        n->next = NULL;     //set node to point to NULL

        if ( ptrTail == NULL )  // or if ( ptrTail == nullptr )
        {
            ptrHead = n;
            ptrTail = n;
        }
        else
        {
            ptrTail->next = n;
            ptrTail = n;
        }

        size++;
    }



    //this is the test code from my main function
              int main()
        {
            //test code
            linkedList list;

            list.addFront(40);
            list.addFront(30);
            list.addFront(20);
            list.addFront(10);
            list.addFront(0);
            list.addBack(50);
            list.addBack(60);

            list.display(); //50 60 7  (the 7 is the count/size of the linked list)
            cout << endl;
        }

【问题讨论】:

  • 这并不能回答您的问题,但您是否考虑过创建双向链表?如果您将 'n->prev' 指针添加到 'node',您将不必在每次将项目添加到列表末尾时遍历整个列表。
  • 我还没有学习双向链表。我正在努力向上。不过感谢您的提示。 :)
  • 您已经确定了单链表的主要弱点。在一些非常具体的场景中,以线性方式从头到尾遍历完美地模拟了所需的功能。例如,除非您添加退出条件来中断循环,否则 foreach 块将如何从头到尾处理每个语句。双向链表的工作原理相同,但包含双向的引用和指针。它增加了更多开销,但在某些特定情况下很有用,就像单链表一样。

标签: c++ insert linked-list traversal


【解决方案1】:
for(int i=1; i<size; i++)
   pCurrent = pCurrent->next;

pCurrent = n;

这会奏效。但是您必须将大小变量保持为链表的实际大小。

或者如果您想始终添加元素,您可以按照以下步骤操作。 保留一个额外的节点尾部并将元素添加到其中。

if(head == NULL)
{
   head = n;
   tail = n;
}
else
{
   tail->next = n;
   tail = tail->next;
}

【讨论】:

    【解决方案2】:

    您没有显示您的linkedList 的定义。

    所以我只能假设它有数据成员 ptrTail 和 ptrHead。在这种情况下,函数将如下所示

    void linkedList::addBack(int addData)
    {
       node* n = new node; //create new node
       n->data = addData;  //input data
       n->next = NULL;     //set node to point to NULL
    
       if ( ptrTail == NULL )  // or if ( ptrTail == nullptr )
       {
          ptrHead = n;
       }
       else
       {
          ptrTail->next = n;
       }
       ptrTail = n;
    
       size++;
    }
    

    函数addFront可以类似的方式定义

    void linkedList::addFront(int addData)
    {
       node* n = new node; //create new node
       n->data = addData;  //input data
    
       if ( ptrHead == NULL )  // or if ( ptrHead == nullptr )
       {
          ptrTail = n;
       }
    
       n->next = ptrHead;
       ptrHead = n;
    
       size++;
    }
    

    更多功能

    void linkedList::removeFront()
    {
        if ( ptrHead != NULL )
        {
            if ( ptrTail == ptrHead ) ptrTail = NULL;
            node* n = ptrHead;
            ptrHead = ptrHead->next;
            delete n;
            size--;
        }
    }
    

    【讨论】:

    • 如果您合并ptrTail = n;,我很乐意放弃我的答案并提高这个答案(我知道,它变化无常,但它是如此接近并且您先发布......)
    • 我尝试以这种方式实现它,但我得到了一个奇怪的结果。我的输出是 0 10 20 30 40,在后面加上 50 和 60 后,我的输出只有 50 60。
    • @JosephK 正如我所说,你没有显示你的类定义。此错误可能是其他错误成员函数定义的结果。例如,是否在构造函数中将 ptrHead 和 ptrTail 初始化为零。
    • @JosephK 有了这个类定义,函数必须正常工作。
    • @JosephK 如果有错误,那么它在函数 addFront 中。
    【解决方案3】:

    试试这个

    node* pCurrent = ptrHead;
    if( pCurrent != NULL ){
        //find tail
        while (pCurrent->next != NULL)
            pCurrent = pCurrent->next;
    
        // add new node at end of tail
        pCurrent->next = n;
        } else {
            pCurrent = n;
        }
    }
    

    【讨论】:

    • 这行得通。非常感谢您,好先生。我一直试图将我的 pCurrent 节点分配给我的尾节点,但我把事情搞混了。
    • @JosephK 这不起作用,因为 ptrHead 可以等于 NULL。这是一个无效的代码。看我的帖子。
    • 如果列表在一个空列表上被管理为ptrHead == NULL,这个答案是错误的。如果该列表归因于头-前哨-节点哲学(这既令人困惑又令人讨厌),它可能起作用。但是不检查就取消引用几乎总是错误的。
    猜你喜欢
    • 1970-01-01
    • 2014-02-02
    • 2013-11-13
    • 1970-01-01
    • 2015-06-14
    • 1970-01-01
    • 2018-10-16
    • 1970-01-01
    相关资源
    最近更新 更多