【问题标题】:Linked list push method链表推送方法
【发布时间】:2012-03-13 03:17:00
【问题描述】:

我正在使用 C++ 编写一个模板化的通用链表,但我遇到了 push() 方法的问题。我想我知道问题所在,但我无法找到解决方案。这是我的推送方法。

template <class T> void DLL<T>::pushFront(T value) {
  Node<T> node(value);
  temp = node;
  temp->setPrev(*head);
  temp->setNext(*(head->getNext()));
  head->setNext(*temp);
  temp->getNext()->setPrev(*temp);                                                                                                                                    
  this->length++;                                                                                                                                                     
}

在将一些整数推入列表后,遍历列表并打印出值会导致打印出似乎是内存中随机空间的数字。我认为这是因为在 push 函数返回后 node 变量被销毁有关。任何人都知道为什么这不起作用?所有 setNext/Prev() 和 getNext/Prev() 函数在我的其他测试中都能正常工作。我被难住了……

编辑*

变量 head 和 temp 是 Node*

类型的全局变量

【问题讨论】:

  • 第 3 行应该是 temp = &node 吗?

标签: c++ linked-list


【解决方案1】:

您应该使用指针将节点存储在列表中。

Node<T> node(value);
temp = node;

此代码超出范围后,分配给“节点”的内存将被释放,从而破坏您的链表。改用指针:

template <class T> void DLL<T>::pushFront(T value) {
  Node<T> *node = new Node<T>(value);
  node->setPrev(head);
  node->setNext(head->getNext());
  head->setNext(node);
  node->getNext()->setPrev(node);
  this->length++;
}

你的类节点应该是这样的:

template<class T> class Node {
public:
    /* ... */
private:
    Node<T> *next;
    T data;
};

【讨论】:

  • 即使这样做仍然有相同的结果。我需要一些特定的方法来保持“new Node(value)”的存在吗?在方法里面声明就可以了吧?
  • 是的,没关系。你的节点结构可能有问题,因为你只给了我们那个方法,所以很难说它是什么。
【解决方案2】:

首先,head 应该是一个全局的——它应该是 DLL 的成员,所以每个 dll(可怜的缩写,IMO)都有一个头部(并且可能是一个尾)。

其次,getnextsetnextgetprevsetprev 在我看来是 100% 毫无意义的浪费时间。通过使用它们而不是读取/分配变量,您在封装或可读性方面一无所获。

第三,正如@fontanini 已经指出的那样,当你push 一个节点时,你需要实际分配一个节点,而不是每次都尝试重用单个节点。

第四,在我看来,您使所涉及的指针操作过于复杂,可能至少部分是由于getnext/setprev 等的丑陋/不可读性等。一旦你有了一个节点,将其拼接到链表的前面只需要三个操作(加上增加长度):

template <class T> 
void DLL<T>::pushFront(T value) { 
   node<T> *tmp = new node<T>(value);
   tmp -> next = head;
   tmp -> next -> prev = tmp;
   head = tmp;
   ++length;
}

完成后,我发现将指针传递给节点的 ctor 会更简单一些。在这种情况下,结果是这样的:

template <class T> 
void DLL<T>::pushFont(T value) { 
   // These parameters are value, prev, and next, respectively.                             
   node<T> *tmp = new node<T>(value, NULL, head);
   tmp->next->prev = tmp;
   head = tmp;
   ++length;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-18
    • 1970-01-01
    • 2021-05-20
    • 2011-12-02
    • 1970-01-01
    • 2013-07-23
    相关资源
    最近更新 更多