C++ 在双链接列表上执行操作时,您应该记住什么?

C++ 在双链接列表上执行操作时,您应该记住什么?,c++,data-structures,C++,Data Structures,例如,我的指导老师说,在使用链表进行操作时,不要释放任何内存,并删除指针。此外,他还说,在对双链表进行操作时,应该确保边缘情况正常。有人能详细介绍一下吗?我不确定我是否完全明白他的意思 例如,这是我们正在处理的链表类型: struct Node { Node *next; Node *prev; T datum; }; Node *first; // points to first Node in list, or 0 if lis

例如,我的指导老师说,在使用链表进行操作时,不要释放任何内存,并删除指针。此外,他还说,在对双链表进行操作时,应该确保边缘情况正常。有人能详细介绍一下吗?我不确定我是否完全明白他的意思

例如,这是我们正在处理的链表类型:

 struct Node {
        Node *next;
        Node *prev;
        T datum;
    };

Node *first;   // points to first Node in list, or 0 if list is empty
Node *last;    // points to last Node in list, or 0 if list is empty

在处理指针时,您总是希望确保删除不再使用的任何新对象。这样就不会有任何内存泄漏


例如,当插入元素时,边缘条件是否适用于空列表,当项目将作为第一个元素插入时,是否作为最后一个元素插入?通常,在执行INSERT时,我们对一个典型元素(即在现有列表中间的一个)执行逻辑。但它应该适用于所有情况。我提到的情况可以被视为边缘条件,并且必须为列表中要执行的每个操作考虑。

在处理指针时,始终要确保删除任何不再使用的
新对象。这样就不会有任何内存泄漏


例如,当插入元素时,边缘条件是否适用于空列表,当项目将作为第一个元素插入时,是否作为最后一个元素插入?通常,在执行INSERT时,我们对一个典型元素(即在现有列表中间的一个)执行逻辑。但它应该适用于所有情况。我提到的情况可以被视为边缘条件,并且必须为列表中要实现的每个操作考虑。

因为您使用的是“结构”,而不是“类”,所以为每个节点的操作实现一些函数

更新: 我之所以提到
class
,是因为我所评论的函数通常是作为对象方法实现的,在链表的面向对象版本中, 然而,这些操作也适用于过程编程

例如:

struct Node {
        Node *next;
        Node *prev;
        T datum;
    };

Node *first;   // points to first Node in list, or 0 if list is empty
Node *last;    // points to last Node in list, or 0 if list is empty

void NodesLink(Node* A, Node* B)
{
  if ((A != NULL) && (B != NULL))
  {
     A->next = B;
     B->prev = A;
  }
} // void NodesLink (...)

void NodesInsertAfter(Node* A, Node* NewNode)
{
  if ((A != NULL) && (NewNode != NULL))
  {
     Node* B = A->next;
     NodesLink(A, NewNode);
     NodesLink(NewNode, B);
  }
} // void NodesLink (...)

独立的实用程序函数将使您的代码更加一致,并且易于调试和修复。

因为您使用的是“struct”而不是“class”,所以为每个节点的操作实现一些函数

更新: 我之所以提到
class
,是因为我所评论的函数通常是作为对象方法实现的,在链表的面向对象版本中, 然而,这些操作也适用于过程编程

例如:

struct Node {
        Node *next;
        Node *prev;
        T datum;
    };

Node *first;   // points to first Node in list, or 0 if list is empty
Node *last;    // points to last Node in list, or 0 if list is empty

void NodesLink(Node* A, Node* B)
{
  if ((A != NULL) && (B != NULL))
  {
     A->next = B;
     B->prev = A;
  }
} // void NodesLink (...)

void NodesInsertAfter(Node* A, Node* NewNode)
{
  if ((A != NULL) && (NewNode != NULL))
  {
     Node* B = A->next;
     NodesLink(A, NewNode);
     NodesLink(NewNode, B);
  }
} // void NodesLink (...)

独立的实用程序函数将使您的代码更加一致,并且易于调试和修复。

一些边缘情况可能是
(a) 无节点
(b) 只有一个节点
(c) 在头部/尾部添加节点
(d) 遍历列表时避免无限循环
(e) 避免内存泄漏和指针悬空


这些是应该进行的基本检查。

一些边缘情况可能是
(a) 无节点
(b) 只有一个节点
(c) 在头部/尾部添加节点
(d) 遍历列表时避免无限循环
(e) 避免内存泄漏和指针悬空


这些是应该做的基本检查。

写一个实现,一切都会变得清晰。问问你的教授,这就是他在那里的目的。边缘案例:=>极端案例。1) 空列表。2) 列表中包含1个元素。3) 列表的开头是列表的结尾。5)正常情况(列表中的一个元素)。当你处理动态内存时,你应该记住你在双链接列表上做操作,你应该记住的最重要的事情是不要把它搞砸。写一个它的实现,一切都会变得清晰。问你的教授,这就是他在那里的目的。边缘案例:=>极端案例。1) 空列表。2) 列表中包含1个元素。3) 列表的开头是列表的结尾。5)正常情况(列表中的一个元素)。当你处理动态内存时,你应该记住你在一个双链接列表上做操作,你应该记住的最重要的事情是不要把它拧起来。C++中
struct
class
之间的唯一区别是默认访问。因此,我不明白“既然你使用了<代码>结构>代码>,而不是<代码>类< /C> >,在C++中,<代码>结构> <代码>和<代码>类< /代码>之间的唯一区别是默认访问。所以我不明白“既然您使用的是
结构,而不是
”的意思。