在列表中插入一个节点的副本(有条件)

Insert a copy of a node in a list (with condition)

练习要求插入值 x 的副本(这也是要在列表中搜索的值),但前提是该位置是另一个值 n 的倍数。没有指定副本应该插入到x值之前还是之后。

我的问题是并非在所有情况下都插入了副本。我认为问题是当我插入新节点时,列表位置的计数器也计算这个新值,报告不正确的结果。

我该如何解决这个问题?还是我弄错了?

我在学习。也许我的尝试是完全错误的,因此我要求至少有一个像样的解释,以便我可以改进。

我的代码:

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

typedef struct data Node;

Node *newnode(void)
{
    return malloc(sizeof(Node));
}

Node *creat_list()
{
    Node *lis, *p, *last;
    int x;

    printf("\n insert data: ");
    scanf("%d", &x);

    if(x <= 0)
    {
        lis = NULL;
    }
    else
    {
        last = newnode();

        lis = last;
        last->d = x;
        last->next = NULL;

        printf(" insert data: ");
        scanf("%d", &x);

        while(x > 0)
        {
            p = newnode();
            p->d = x;
            p->next = NULL;
            last->next = p;
            last = p;
            printf(" insert data: ");
            scanf("%d", &x);

        }
    }
    return (lis);
}

void print_list(Node *lis)
{
    printf("\n List: \n");
    printf(" -> ");

    while(lis != NULL)
    {
        printf("%d", lis->d);
        printf(" -> ");
        lis = lis->next;
    }
    printf("NULL\n\n");
}

void insertCopy(int x, int n, Node **lis)
{
    int pos = 1;

    Node *p, *head;

    head = *lis;


    if ((head->d == x) && (pos % n == 0))
    {
            p = newnode();
            p->d = x;
            p->next = head;
            *lis = p;
    }

    if (head->next != NULL)
    {
        pos = 2;

        while(head->next != NULL)
        {
            if ((head->next->d == x) && (pos % n == 0))
            {
                p = newnode();
                p->d = x;
                p->next = head->next;
                head->next = p;
            }
            else
            {
                head = head->next;
            }
            pos++;
        }
    }
}

int main(void)
{   
    Node *l1;

    int x = 1;
    int n = 3;

    l1 = creat_list();

    print_list(l1);

    insertCopy(x, n, &l1);

    print_list(l1);

    return 0;
}

示例:

输入:

2 3 1 6 1 2 2 6 1 5 0

给予

列表:

2->3->1->6->1->2->2->6->1->5->NULL

x = 1, n = 3;

预期输出为:

2->3->1->1->6->1->2->2->6->1->1->5->NULL

我的输出是:

2->3->1->1->6->1->2->2->6->1->5->NULL

您的代码中存在更多问题,但您要求的问题(根据您的示例)是您只获得了一个额外的节点,而您期望获得两个额外的节点。

预计:

2->3->1->1->6->1->2->2->6->1->1->5->NULL

实际:

2->3->1->1->6->1->2->2->6->1->5->NULL
                           ^^^
                        A node is missing here

问题在于插入额外节点时处理 head 的方式。

尝试改变这个:

        if ((head->next->d == x) && (pos % n == 0))
        {
            p = newnode();
            p->d = x;
            p->next = head->next;
            head->next = p;
        }

进入

        if ((head->next->d == x) && (pos % n == 0))
        {
            p = newnode();
            p->d = x;
            p->next = head->next;
            head->next = p;
            head=p->next;       // Add this line
        }

您原始代码的问题是您没有正确移动head。因此计数器 pos 与原始列表不同步。