C ++中的简单链表实现

时间:2010-02-17 02:22:01

标签: c++ pointers linked-list

我是第一个C ++课程的编程学生,最近我们介绍了链接列表,并且我们获得了一个实现简单编程的任务。我编写了除pop_back()函数之外的所有函数,该函数用于返回指向需要在Node中删除的Main()的指针。在实际功能中不执行Node删除。所以我的问题是:

您是否愿意帮助我指出pop_back()功能正确的方向?另外,如果你发现其他任何我做错了,请告诉我。

此外,此链接列表仅用于处理字符串。在这种情况下,一个购物清单,所以一个字符串表示项目数量(1,2),一个字符串表示项目类型。 (牛奶,鸡蛋等)

下面我列出了我的列表&节点类实现,这样你就可以了解我到目前为止所做的工作。

Node.cpp

Node::Node(void)
{
    descrip = " ";
    quantity = " ";
    previous = NULL;
    next = NULL;
}
Node::Node(string q, string d)
{
    descrip = d;
    quantity = q;
    previous = NULL;
    next = NULL;
}
Node* Node::GetNext()
{
    return next;
}
Node* Node::GetPrevious()
{
    return previous;
}
void Node::SetNext(Node * setter)
{
    next = setter;
}
void Node::SetPrevious(Node * setter)
{
    previous = setter;
}

List.cpp

List::List(void)
{
   first = NULL;
   last = NULL;
   numNodes = 0;
}
Node* List::GetFirst()
{
    return first;
}
Node* List::GetLast()
{
    return last;
}
void List::SetFirst(Node* setter)
{
    first = setter;
}
void List::SetLast(Node* setter)
{
    last = setter;
}
int List::GetNumNodes()
{
    return numNodes;
}
void List::push_front(Node* item)
{
   if (first == NULL)
   {
       first = item;
       last = item;
   }
   else 
   {
       Node* pFirst = first;
       item->SetNext(pFirst);
       first = item;
       numNodes++;
   }
}
void List::push_back(Node * item)
{
    if (last == NULL)
    {
       first = item;
       last = item;
    }
    else 
    {
        last->SetNext(item);
        last = item;
        numNodes++;
    }
}
Node* List::pop_front()
{
    Node* temp = first;
    first = first->GetNext();
    if (first == NULL)
    {
        temp = first->GetNext();
        first = p;
    }
    if (first == NULL)
    {
        last = NULL;
    }
    if (numNodes > 0)
    {
        numNodes--;
    }
    return temp;
}
Node* List::pop_back() // this whole function may be wrong, this is just my attempt at it
{
    Node* temp;
    temp = first;

    while((temp->GetNext()) != NULL)
        // im stuck here

}

4 个答案:

答案 0 :(得分:4)

一些指示:

0x1243bfa3
0x45afc56e
0xdeadbeef

更多指示:

  1. 您应该更喜欢在初始化列表中初始化类成员,而不是在构造函数的主体中初始化。

  2. 在C ++中,与C89不同,我们声明并定义一个没有参数的函数void f();,而不是void f(void);

  3. 在C ++中,我们通常使用0重置指针,而不是NULL

    请参阅下文,了解我在代码中的含义。

  4. 好的C ++代码会尝试利用RAII。这意味着在大多数情况下避免使用原始指针。在这种情况下,普通的旧std::auto_ptr<>将完全替代原始Node*指针。但是,我认为这里的部分练习是指针算术,所以我只是留下这个作为旁注。

  5. 如果您附加了类声明,它对我们很有用。我假设所有那些访问者和变异者GetFirst()SetFirst()等都存在,因为它们是公开的。这是个坏主意。首先,它们暴露私有指针,这会破坏访问者的整个点。其次,他们没有做任何特别的事情,所以他们只是额外的代码 - 这意味着额外的错误空间。这让我想到了下一点。

  6. 你的变异者是不正确的。您盲目地为私有成员指针指定一个新值,而不删除之前的内容。这是内存泄漏。

  7. 当列表为空时,曾试过pop_front()吗?

  8. 最后,8是一个圆数,是时候我们得到了手头的问题。 pop_back()。我的问题是,如果您如此精心维护指向列表最后一个节点的指针,为什么要一直遍历列表?实际上,如果您不打扰维护指向列表末尾的指针,那么您必须遍历到最后一个节点才能弹出它。为此你正朝着正确的方向前进。除此之外......

  9. 当您通过指针访问成员时,如first->GetNext()总是确保first不是空指针 - 或者在函数中指出您认为指针不为空的文档注释。

  10. 这些应该可以帮到你。

    代码中的第1,2和3点:

    Node::Node()
    : descrip(" "), quantity(" "), previous(0), next(0)
    {
    }
    

答案 1 :(得分:1)

所以,如果我理解这一点你只想运行你的链表,直到你到达链表中的最后一个节点并返回它的指针? 我非常肯定你有什么会做的,除了

Node* List::pop_back() // this whole function may be wrong, this is just my attempt at it  
{  
    Node* temp;  
    temp = first;  
    while(temp->GetNext() != NULL)  
    {  
        temp = temp->GetNext();  
    }  
    return temp;  
}

因此,如果我正确阅读它,它将不断循环,直到它到达后面的行中没有的节点,然后返回它。

答案 2 :(得分:0)

我喜欢之前的海报答案,但有一件事你可能要记住,如果你有一个空列表。然后你的第一个指针将等于NULL,你将尝试基本上调用NULL-&gt; GetNext()和Seg Fault。我认为你可以稍微编辑上面的代码,但仍然可以这样工作:

Node* List::pop_back() 
{  
    Node* temp;  
    temp = first;  
    while(temp != NULL && temp->GetNext() != NULL)  
    {  
        temp = temp->GetNext();  
    }  
    return temp;  
}

如果列表中没有任何内容并且仍能正常工作,则此函数将返回NULL。

答案 3 :(得分:-1)

如果您还发布了课程声明,肯定会帮助我。我无法保证以下内容是正确的,但对我来说是有意义的

Node* List::pop_back()
{
  Node *temp = NULL;
  if(numNodes == 1) 
  {
    temp = first;
    // setting the list pointers to NULL
    first = NULL;
    // setting the list pointers to NULL 
    last = NULL; 
    //You should also probably remove the links from your node 
    //to the next and previous nodes but since you didn't specify 
    //this it is up to you
    numNodes--;
  }
  else if(numNodes > 1) //more than one element
  {
    //the pointer you want to return
    temp = last;
    //For clarity I am creating another variable here
    Node *newLast = temp->GetPrevious(); 
    //Setting the new last node to point at nothing so now temp 
    //is "disconnected from the list"
    newLast->next = NULL; 
    //the last pointer of the list is now pointing at the new last node
    last = newLast;         
//You should also probably remove the links from your node 
//to the next and previous nodes but since you didn't specify this it is up to you
        numNodes--; //decrement the counter
      }
      return temp;
    }