Linked list 将一个项目从一组1个元素中出列

Linked list 将一个项目从一组1个元素中出列,linked-list,queue,Linked List,Queue,给定一个带有前后指针的队列类型的单链表实现,当您从一组1元素中取出一个项目时,是否需要将后指针设置为null 我正在阅读Nell Dale的C++ +数据结构,第5.2章他用DeStand方法编写: if (front == NULL) rear == NULL; 我想知道为什么这是必要的。我能想到的唯一原因是他对空集实现排队的方式: if (rear == NULL) front = newNode; else rear->next = newNode; rear = ne

给定一个带有前后指针的队列类型的单链表实现,当您从一组1元素中取出一个项目时,是否需要将后指针设置为null

我正在阅读Nell Dale的C++ +数据结构,第5.2章他用DeStand方法编写:

if (front == NULL)
  rear == NULL;
我想知道为什么这是必要的。我能想到的唯一原因是他对空集实现排队的方式:

if (rear == NULL)
  front = newNode;
else
  rear->next = newNode;
rear = newNode;

但是,如果(front==NULL)要获得正确的代码,您需要在每个操作中维护数据结构不变量,那么不能将此条件更改为
。按照原始代码的编写方式,不变量如下所示:

  • A1:
    front
    指向第一个元素(如果存在)<代码>空值
否则
  • A2:
    rear
    指向最后一个元素(如果存在)<代码>空值否则
  • 您声称不变量可以是:

    • B1:
      front
      指向第一个元素(如果存在)<代码>空值否则
    • B2:
      rear
      指向最后一个元素(如果存在)
    现在这些是相似的,但完全不同。当列表为空时,B不变量不需要任何特定值
    rear
    。现在您可以使用B不变量来实现列表,当然,因为它允许区分空状态和非空状态,这就足以提供正确的实现

    但这并不能说明A或B在实践中是否更好。如果使用B不变量,则窥视最后一个元素的函数不能简单地返回
    rear
    的值,因为如果队列为空,其值可以是任何值;您必须先测试
    front

    // for the A2 invariant
    return rear ;
    
    // for the B2 invariant
    return ( front == NULL ) ? NULL : rear ;
    
    这归结为是否要在您退出队列时进行测试和分配,或者是否要在查看最后一个元素时进行测试。这是一个优化问题,而不是正确性问题。如果您不需要查看最后一个元素,您可以为此进行优化

    综上所述,这是过早优化危害的主要原因。向
    NULL
    分配额外的指针几乎永远不会成为性能问题。更可能出现的问题是,当现有代码使用B不变量时,当有人依赖a不变量时,在维护期间引入缺陷。A不变量在认知上更简单,因为
    前面
    后面
    是类似地设置的,两者都没有特殊的行为。B不变量可能表现得更好,但代价是复杂性。根据你的情况,两种选择都可能更好


    这个故事的寓意是:始终记录您的不变量。

    要获得正确的代码,您需要在每次操作中维护数据结构不变量。按照原始代码的编写方式,不变量如下所示:

    • A1:
      front
      指向第一个元素(如果存在)<代码>空值否则
    • A2:
      rear
      指向最后一个元素(如果存在)<代码>空值否则
    您声称不变量可以是:

    • B1:
      front
      指向第一个元素(如果存在)<代码>空值否则
    • B2:
      rear
      指向最后一个元素(如果存在)
    现在这些是相似的,但完全不同。当列表为空时,B不变量不需要任何特定值
    rear
    。现在您可以使用B不变量来实现列表,当然,因为它允许区分空状态和非空状态,这就足以提供正确的实现

    但这并不能说明A或B在实践中是否更好。如果使用B不变量,则窥视最后一个元素的函数不能简单地返回
    rear
    的值,因为如果队列为空,其值可以是任何值;您必须先测试
    front

    // for the A2 invariant
    return rear ;
    
    // for the B2 invariant
    return ( front == NULL ) ? NULL : rear ;
    
    这归结为是否要在您退出队列时进行测试和分配,或者是否要在查看最后一个元素时进行测试。这是一个优化问题,而不是正确性问题。如果您不需要查看最后一个元素,您可以为此进行优化

    综上所述,这是过早优化危害的主要原因。向
    NULL
    分配额外的指针几乎永远不会成为性能问题。更可能出现的问题是,当现有代码使用B不变量时,当有人依赖a不变量时,在维护期间引入缺陷。A不变量在认知上更简单,因为
    前面
    后面
    是类似地设置的,两者都没有特殊的行为。B不变量可能表现得更好,但代价是复杂性。根据你的情况,两种选择都可能更好


    这个故事的寓意是:总是记录你的不变量。

    你能解释一下记录不变量的重要性吗?我想答案已经提供了。代码段提供了假定不同不变量的函数的替代实现。如果你写错了,你就写了有缺陷的代码。实现任何给定类总是有多种方法,但这些不同的方法(通常)并不相互兼容。如果不指定不变量,则很容易将本身正确但不正确的实现片段错误地混合在一起。能否解释记录不变量的重要性?我想答案已经提供了。代码段提供了假定不同不变量的函数的替代实现。如果你写错了,你就写了有缺陷的代码。实现任何gi都有多种方法