删除链接列表中的每个第三个节点

时间:2016-03-15 16:54:56

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

我有一个删除链表中每个第三个节点的函数:

void tricimate()
    {
    node * toDelete = head->next->next;
    while (toDelete != NULL)
    {
        if (toDelete->next == NULL)
        {
            tail = tail->prev;
            tail->next = NULL;
            delete toDelete;
            break;
        }
        node * ahead = toDelete->prev;
        node * behind = toDelete->next;
        ahead->next = behind;
        behind->prev = ahead;
        delete toDelete;
        toDelete = behind->next->next;
    }

}

它可以工作但是当我尝试添加值为47的节点时,它不会添加它。我有这个:

29 7 2 3 31 37

我什么时候应该这样:

29 7 2 3 31 37 47

这是我在链表背面添加新节点的代码:

void addBack(int x)
{
    node * newItem = new node;
    if (head == NULL && tail == NULL)
    {
        newItem->data = x;
        newItem->next = NULL;
        newItem->prev = NULL;
        head = newItem;
        tail = newItem;
    }
    else
    {
        newItem->data = x;
        newItem->next = NULL;
        newItem->prev = tail;
        tail->next = newItem;
        tail = newItem;
    }
}

我不明白什么是错的,因为addBack之前正在工作。但在我使用tricimate功能后,它停止工作。我做错了什么?

2 个答案:

答案 0 :(得分:1)

查看您的tricimate功能,看起来像是一种过度思考的情况,并导致“过度编码”。

要删除每个第三个节点(假设链表至少有3个节点),代码可以将计数器设置为1,在循环中递增计数器,如果计数器可均分为3,则删除该节点

你应该做的是写一个从列表中删除任何节点的函数(称之为remove_node)。如果你有,那么删除每个第三个节点的功能变得简单:

void tricimate()
{
   int counter = 1;
   node* curNode = head;
   while (curNode)
   {
      node *nextNode = curNode->next;  // save for the next iteration
      if ( counter % 3 == 0 )  // if we're on the node we want to delete...
         remove_node(curNode);  // remove it.
      ++counter;              // increment count
      curNode = nextNode;     // go to next node.
   }   
}

请注意,我没有实现remove_node功能。我不知道链接列表的其余部分是如何实现的,所以如果我尝试编写remove_node函数,不想过多考虑它。但至少,它应该具有删除节点的功能 - 如果没有,它缺少任何链表实现应该具有的基本功能。

答案 1 :(得分:0)

该功能可以通过以下方式定义

void tricimate()
{
    node *current = head;

    while ( current && ( current = current->next ) && ( current = current->next ) )
    {
        node *toDelete = current;

        current->prev->next = current->next;
        if ( current->next != nullptr )
        {
            current->next->prev = current->prev;
        }
        else
        {
            tail = current->prev;
        }

        current = current->next;

        delete toDelete;
    }
}

至于你的功能,那么对于初学者来说,即使它的第一个陈述已经错了

void tricimate()
    {
    node * toDelete = head->next->next;
    //....

因为一般headhead->next可以等于nullptr