运行直到某个值链表

Running until a certain value linked list

我想对节点求和直到达到 0 并用新值更新原始链表。

注意:它会跳过0,直到到达要计算和的数字或链表的末尾。

节点定义:

struct Node {
int data;
Node* next;
};

void updateLinkedList(Node* head)
{
Node* currentNode = head;

int temp = 0;
int sum = 0;


while (currentNode != NULL)
{
    temp = currentNode->data;

    while(temp != 0)
    {
        sum = sum + currentNode->data;
        currentNode = currentNode->next;
    }
}
}

我正在尝试做下一件事:

用户输入链表:

1 2 0 5 3 0 4

更新链表:

3 8 4

该功能可以实现例如下面的方式

void updateLinkedList( Node * &head )
{
    for ( Node **current = &head; *current != nullptr; )
    {
        if ( ( *current )->data == 0 )
        {
            Node *tmp = *current;
            *current = ( *current )->next;
            delete tmp;
        }
        else
        {
            while ( ( *current )->next != NULL && ( *current )->next->data != 0 )
            {
                ( *current )->data += ( *current )->next->data;
                Node *tmp = ( *current )->next;
                ( *current )->next = ( *current )->next->next;
                delete tmp;
            }

            current = &( *current )->next;
        }
    }
}

这里有一个演示程序。

#include <iostream>

struct Node
{
    int data;
    Node *next;
};

void clear( Node * &head )
{
    while (head != nullptr)
    {
        Node *tmp = head;
        head = head->next;
        delete tmp;
    }
}

void assign( Node * &head, const int a[], size_t n )
{
    clear( head );

    for (Node **current = &head; n--; current = &( *current )->next)
    {
        *current = new Node{ *a++, nullptr };
    }
}

std::ostream &display( const Node * const &head, std::ostream &os = std::cout )
{
    for (const Node *current = head; current != nullptr; current = current->next)
    {
        os << current->data << " -> ";
    }

    return os << "null";
}

void updateLinkedList( Node * &head )
{
    for (Node **current = &head; *current != nullptr; )
    {
        if (( *current )->data == 0)
        {
            Node *tmp = *current;
            *current = ( *current )->next;
            delete tmp;
        }
        else
        {
            while (( *current )->next != NULL && ( *current )->next->data != 0)
            {
                ( *current )->data += ( *current )->next->data;
                Node *tmp = ( *current )->next;
                ( *current )->next = ( *current )->next->next;
                delete tmp;
            }

            current = &( *current )->next;
        }
    }
}

int main()
{
    Node *head = nullptr;

    const int a[] = { 0, 0, 1, 2, 0, 5, 3, 0, 4 };
    const size_t N = sizeof( a ) / sizeof( *a );

    assign( head, a, N );

    display( head ) << '\n';

    updateLinkedList( head );

    display( head ) << '\n';

    clear( head );
}

程序输出为

0 -> 0 -> 1 -> 2 -> 0 -> 5 -> 3 -> 0 -> 4 -> null
3 -> 8 -> 4 -> null

在现代 C++ 中,您很少希望直接处理内存分配。您通常会使用标准库或其他库中的 类。那是因为很容易忘记一些东西并导致整个程序崩溃或创建 memory leaks.

熟悉内存分配和知道如何手动实现链表很重要。这是由 Vlad 的回答处理的。

我想补充一点:将来,您可能希望使用更高级别的功能。如果您使用标准容器之一 std::forward_list,这就是我编写函数的方式。

void updateLinkedList(std::forward_list<int>& list)
{
    auto lastIt = list.before_begin();

    for (auto it = std::begin(list); it != std::end(list);)
    {
        if (*it)
        {
            lastIt = it++;
            int sum = *lastIt;

            while (it != std::end(list) && *it)
            {
                sum += *it;
                it++;
                list.erase_after(lastIt);
            }

            *lastIt = sum;
        }
        else
        {
            it++;
            list.erase_after(lastIt);
        }
    }
}

编辑:用于测试:

#include <forward_list>
#include <iostream>

void printList(const std::forward_list<int>& list)
{
    std::cout << "{ ";
    for (auto& i : list)
    {
        std::cout << i << ", ";
    }
    std::cout << "}\n";
}

void updateLinkedList(std::forward_list<int>& list)
{
    auto lastIt = list.before_begin();

    for (auto it = std::begin(list); it != std::end(list);)
    {
        if (*it)
        {
            lastIt = it++;
            int sum = *lastIt;

            while (it != std::end(list) && *it)
            {
                sum += *it;
                it++;
                list.erase_after(lastIt);
            }

            *lastIt = sum;
        }
        else
        {
            it++;
            list.erase_after(lastIt);
        }
    }
}

int main() {
    std::forward_list list{
        0, 0, 1, 2, 0, 5, 3, 0, 0, 4, 0, 0, 0,
    };

    printList(list);
    updateLinkedList(list);
    printList(list);
}

On compiler explorer.

在您的函数中,如果 temp!=0 的初始值,则内部 while 循环似乎是一个无限循环,因为循环内的任何地方都没有更新 temp。 currentNode 指向的节点得到更新,但 temp 指的是在进入内部 while 循环之前 currentNode 最初指向的节点包含的值。