【问题标题】:Pointing to the wrong position in doubly linked list?指向双向链表中的错误位置?
【发布时间】:2020-12-11 06:56:02
【问题描述】:

我的双向链表有两个虚拟节点,头和尾。 addToFirst 函数非常适合我,但是当我尝试使用与 addToBack 相同的算法时,它会一直为我打印虚拟节点。为什么会这样?

DList *init( )
{
   head = ( DList * ) malloc( sizeof( DList ) );
   if ( head == NULL ) {
      prtError( "Insufficient memory!" );
      return( NULL );
   }
   
   tail = ( DList * ) malloc( sizeof( DList ) );
   if ( tail == NULL ) {
      prtError( "Insufficient memory!" );
      return( NULL );
   } 
     
   head->data = -1;
   tail->data = -1;   
   head->next = tail;
   head->prev = NULL;  
   tail->next = NULL; 
   tail->prev = head;
   return ( head );  /* indicates no error */ 
}

/* print function */ 
void prtList( )
{
   DList *p;
   for ( p = head->next; p != tail; p = p->next )
        printf( "%4d", p->data );
   printf( "\n");
}

DList *insertFirst( int d )
{
                
   /***** ADD YOUR CODE HERE *****/
   DList *first = ( DList * ) malloc( sizeof( DList ) );
   printf("FF");
   if ( first == NULL ) {
      prtError( "Insufficient memory!" );
      return( NULL );
   }
   /* 2. put in the data  */
    first->data = d;
 
    /* 3. Make next of new node as head and previous as NULL */
    first->next = (head)->next;
    first->prev = NULL;
 
    /* 4. change prev of head node to new node */
    if ((head) != NULL)
        (head)->prev = first;
 
    /* 5. move the head to point to the new node */
    (head)->next = first;

   return first;        // replace this line with your code
}

DList *insertLast( int d )
{

   DList *last = ( DList * ) malloc( sizeof( DList ) );
   printf("LL");
   if ( last == NULL ) {
      prtError( "Insufficient memory!" );
      return( NULL );
   }
   /* 2. put in the data  */
    last->data = d;
 
    /* 3. Make next of new node as head and previous as NULL */
    last->prev = tail->prev;
    last->next = NULL;
 
    /* 4. change prev of head node to new node */
    if ((tail) != NULL)
        (tail)->next = last;
 
    /* 5. move the head to point to the new node */
    (tail) = last;
    //if I try with (tail)->prev = last; then the outputs were empty.


   return last; // replace this line with your code          

}

预期结果:

LL  5
LL  5  10
LL  5  10  15
LL  5  10  15  20
LL  5  10  15  20  25
LL  5  10  15  20  25  30
LL  5  10  15  20  25  30  35
LL  5  10  15  20  25  30  35  40
LL  5  10  15  20  25  30  35  40  45
LL  5  10  15  20  25  30  35  40  45  50
FF   5   5  10  15  20  25  30  35  40  45  50
FF  10   5   5  10  15  20  25  30  35  40  45  50
FF  15  10   5   5  10  15  20  25  30  35  40  45  50
FF  20  15  10   5   5  10  15  20  25  30  35  40  45  50
FF  25  20  15  10   5   5  10  15  20  25  30  35  40  45  50
FF  30  25  20  15  10   5   5  10  15  20  25  30  35  40  45  50
FF  35  30  25  20  15  10   5   5  10  15  20  25  30  35  40  45  50
FF  40  35  30  25  20  15  10   5   5  10  15  20  25  30  35  40  45  50
FF  45  40  35  30  25  20  15  10   5   5  10  15  20  25  30  35  40  45  50
FF  50  45  40  35  30  25  20  15  10   5   5  10  15  20  25  30  35  40  45  50

我的结果:

LL  -1
LL  -1   5
LL  -1   5  10
LL  -1   5  10  15
LL  -1   5  10  15  20
LL  -1   5  10  15  20  25
LL  -1   5  10  15  20  25  30
LL  -1   5  10  15  20  25  30  35
LL  -1   5  10  15  20  25  30  35  40
LL  -1   5  10  15  20  25  30  35  40  45
FF   5  -1   5  10  15  20  25  30  35  40  45
FF  10   5  -1   5  10  15  20  25  30  35  40  45
FF  15  10   5  -1   5  10  15  20  25  30  35  40  45
FF  20  15  10   5  -1   5  10  15  20  25  30  35  40  45
FF  25  20  15  10   5  -1   5  10  15  20  25  30  35  40  45
FF  30  25  20  15  10   5  -1   5  10  15  20  25  30  35  40  45
FF  35  30  25  20  15  10   5  -1   5  10  15  20  25  30  35  40  45
FF  40  35  30  25  20  15  10   5  -1   5  10  15  20  25  30  35  40  45
FF  45  40  35  30  25  20  15  10   5  -1   5  10  15  20  25  30  35  40  45
FF  50  45  40  35  30  25  20  15  10   5  -1   5  10  15  20  25  30  35  40  45

【问题讨论】:

  • 请显示minimal reproducible example 输入和预期输出
  • 不是主要问题,但我发现void prtList( ) 存在一些问题,您使用的是p = head->next;p->data,那么head->data
  • 我不能更改打印功能。 :C

标签: c linked-list doubly-linked-list


【解决方案1】:

这里有几个错误。我建议你再刷一遍基础知识。 这是对您的代码的快速修复。确保了解每项更改。

DList *insertFirst( int d )
{
                
   /***** ADD YOUR CODE HERE *****/
   DList *first = ( DList * ) malloc( sizeof( DList ) );
   printf("FF");
   if ( first == NULL ) {
//      prtError( "Insufficient memory!" );
      return( NULL );
   }
   /* 2. put in the data  */
    first->data = d;
 
    /* 3. Make next of new node as head and previous as NULL */
    first->next = (head)->next;
    first->prev = head;
 
    head->next->prev=first;
    (head)->next = first;

   return head;        // replace this line with your code
}

DList *insertLast( int d )
{

   DList *last = ( DList * ) malloc( sizeof( DList ) );
   printf("LL");
   if ( last == NULL ) {
//      prtError( "Insufficient memory!" );
      return( NULL );
   }
   /* 2. put in the data  */
    last->data = d;
 
    /* 3. Make next of new node as head and previous as NULL */
    last->prev = tail->prev;
    last->next = tail;
    tail->prev->next=last;
    tail->prev=last;
   return head; // replace this line with your code 
}```

【讨论】:

  • 谢谢,这段代码对我有用,我正在尝试找出其中的逻辑。 :D
【解决方案2】:

我怀疑问题是通过您的虚拟元素引入的。与双向列表相比,我更多地使用单链表。但在那种情况下,我有一个不属于列表的头指针。当列表为空时,它为空。这需要特殊情况代码来检查每次插入时列表的头部何时为空。由于插入略有不同。

所以我对你的情况的倾向是有一个头和尾,它们都开始为空。然后当添加第一个元素时,head 和 tail 被设置为指向同一个单个元素。并且元素的下一个和上一个将被设置为空。因为之前或之后没有元素。

但是,我认为双向链表(通常称为双向链表)有一种更简洁的解决方案。在该解决方案中,有一个“虚拟”条目。它既充当头部又充当尾部。所以 *pDummy->next 是指前进到第一个元素, *pDummy->prev 是指后退到最后一个元素。所以在初始化时 pDummy->prev 和 pDummy->next 都指向 pDummy。所以一个空列表实际上有一个元素 pDummy,它被视为列表的开始和结束标记。因此,如果任何 pItem->next == pDummy 则 pItem 位于列表的末尾。如果 pItem->prev == pDummy 则 pItem 位于列表的开头。我相信这个解决方案是更快的实施和更容易实施。由于在开头插入不需要检查空列表,因为 pNext 已经指向列表中的下一个元素而不是 null。

由于我怀疑这是一个编码练习,所以我没有为您编写代码。而是帮助解决所涉及的逻辑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-15
    • 1970-01-01
    • 2018-07-23
    • 2011-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多