c ++从链表中删除给定整数的倍数

c++ remove multiples of a given integer from a linked list

抱歉我的无知,但我是新手,也是 C++ 新手。我正在研究链表,并且有一个练习,我必须编写一个函数来输入一个整数列表和整数 n。该函数必须从列表中删除所有具有 n 和 return 的倍数的节点。我以为我做对了,但我的代码没有输出任何东西。有人可以向我解释为什么吗?谢谢大家!

#include <iostream>
using namespace std;

struct list{
    int val;
    list* next;
};
typedef list* ptr_list;

ptr_list new_node(ptr_list old_node, int value);

ptr_list remove_mult(ptr_list head, int n);

void print_list(ptr_list head);

int main() {

    ptr_list head, p1, p2, p3;
    head = new list;
    head->val = 1;
    p1 = new_node(head, 2);
    p2 = new_node(p1, 3);
    p3 = new_node(p2, 4);

    p3->next = NULL;

    remove_mult(head, 2);
    print_list(head);

    return(0);
}

ptr_list new_node(ptr_list old_node, int value)
{
    old_node->next = new list;
    old_node->next->val = value;
    return old_node->next;
}


ptr_list remove_mult(ptr_list head, int n){
    ptr_list prev, curr;
    prev = head;
    curr = head->next;
    while(curr->next != NULL){
        if((head->val % n) == 0){
            head = head->next;
            curr = curr->next;
        }
        else if((curr->val % n) == 0){
            ptr_list tmp;
            tmp = prev->next;
            prev->next = tmp->next;
            delete tmp;
        }
        prev = curr;
        curr = curr->next;
    }
    if((curr->val % n) == 0){
        prev->next = NULL;
        delete curr;
    }
    return(head);
}

void print_list(ptr_list head){
    while ( head != NULL ){
        cout << head->val << " ";
        head = head->next;
    }
}

这种方法

ptr_list head, p1, p2, p3;
head = new list;
head->val = 1;
p1 = new_node(head, 2);
p2 = new_node(p1, 3);
p3 = new_node(p2, 4);

p3->next = NULL;

//...

ptr_list new_node(ptr_list old_node, int value)
{
    old_node->next = new list;
    old_node->next->val = value;
    return old_node->next;
}

不好,因为它不安全。例如,用户可以向函数传递一个空指针。或者传递的指针的数据成员 next 可以指向一个有效的节点。在这种情况下,它将在函数中被覆盖,并且会出现内存泄漏。或者用户在退出函数后忘记设置最后一个节点的数据成员next为nullptr.

函数remove_mult也无效。例如传递的指针一般可以等于nullptr。在这种情况下,该函数具有未定义的行为。

ptr_list remove_mult(ptr_list head, int n){
    ptr_list prev, curr;
    prev = head;
    curr = head->next;
    //...

该函数也有内存泄漏,因为您忘记删除此 if 语句中的头节点

    if((head->val % n) == 0){
        head = head->next;
        curr = curr->next;
    }

在这个 else 语句中

    else if((curr->val % n) == 0){
        ptr_list tmp;
        tmp = prev->next;
        prev->next = tmp->next;
        delete tmp;
    }

您忘记设置变量的新值 curr

在 if-else 语句之后

    prev = curr;
    curr = curr->next;

您正在设置 prev 一次。这再次导致未定义的行为,例如当当前节点被删除时。

这是一个演示程序,展示了如何实现列表的功能。

#include <iostream>

struct list
{
    int val;
    list* next;
};

typedef list* ptr_list;

ptr_list remove_mult(ptr_list head, int n )
{
    ptr_list curr = head;
    ptr_list prev = nullptr;

    while ( curr != nullptr )
    {
        if ( curr->val % n == 0 )
        {
            ptr_list tmp = curr;

            if ( prev == nullptr )
            {
                head = curr = curr->next;
            }
            else
            {
                curr = prev->next = curr->next;
            }

            delete tmp;
        }
        else
        {
            prev = curr;
            curr = curr->next;
        }
    }

    return head;
}

void print_list( ptr_list head )
{
    for ( ; head != nullptr; head = head->next )
    {
        std::cout << head->val << ' ';
    }
}

ptr_list append_list( ptr_list tail, int val )
{
    if ( tail == nullptr )
    {
        tail = new list { val, nullptr };
    }
    else
    {
        while ( tail->next != nullptr )
        {
            tail = tail->next;
        }

        tail->next = new list { val, nullptr };
        tail = tail->next;
    }

    return tail;
}

int main() 
{
    ptr_list head = nullptr;

    const int N = 10;

    ptr_list tail = nullptr;
    for ( int i = 0; i < N; i++ )
    {
        if ( head == nullptr )
        {
            head = append_list( head, i );
            tail = head;
        }
        else
        {
            tail = append_list( tail, i );
        }
    }

    print_list( head );
    std::cout << '\n';

    head = remove_mult( head, 2 );

    print_list( head );
    std::cout << '\n';

    return 0;
}

它的输出是

0 1 2 3 4 5 6 7 8 9 
1 3 5 7 9