【问题标题】:Josephus problem using a linked list using mallocJosephus 问题使用链表使用 malloc
【发布时间】:2021-12-02 03:41:36
【问题描述】:

我打算在 C 中使用链表解决约瑟夫斯问题,但它不起作用。我尝试了多种方法,所以我很困惑。

#include "stdlib.h"
#include "stdio.h"

struct Node {
    int num;
    struct Node *Next;
};

typedef struct Node *PtrToNode;

int main() {
    int n, m, i;
    PtrToNode p, q;

    printf("Please input n, m\n");
    scanf("%d %d", &n, &m);

    p = (PtrToNode)malloc(sizeof(struct Node));
    p->num = 1;
    p->Next = p;

    for (i = 2; i <= n; i++) {
        q = (PtrToNode)malloc(sizeof(struct Node));
        q->num = i;
        q->Next = p;
        p->Next = q;
        p = q;
    }

    while (q->Next != q) {
        for (i = 1; i <= m; i++)
            p = q->Next;
        q = p;
        printf("%d, ", q->num);
        p->Next = NULL;
        free(q);
    }
    printf("%d\n", p->num);
    free(p);
    //system("pause");
    return 0;
}

我有点了解 struct 函数和 typedef,所以我想我在那里没有任何问题(?)。我猜我在 main 函数中犯了一个错误。

【问题讨论】:

  • p-&gt;Next = p; 可能不正确。同样为某事分配两次将使第一次分配毫无意义。我建议你退后几步,拿一支铅笔和一些纸,在纸上画出你的列表操作,用方框表示节点(和其他变量),用箭头表示指针。写下操作列表,同时在这些操作之后擦除和重绘箭头。一旦这一切似乎都在纸上起作用,就在代码中实现它,但一次只做一点点,中间要进行大量测试。
  • 我建议去掉 typedef。它不提供任何清晰度,仅用于混淆。此外,尽量消除对列表第一个元素的特殊处理。将列表的头部初始化为 NULL,并在与其他节点相同的循环中为其赋值。

标签: c linked-list josephus


【解决方案1】:

一些问题:

  • 第一个循环中的以下赋值创建了一个总是长度为 2 的循环:

    q->Next = p;
    p->Next = q;
    

    目的是链接回 first 节点,但您不再引用第一个节点,只有前一个节点 (p)。所以引入另一个不会移动的变量:head,然后用q-&gt;next=head链接回来。实际上,您可以在 循环之后执行此操作,仅针对添加的最后一个节点。

  • 在下一个循环中,在for 循环内,以下内容将在每次迭代中执行相同的操作:

    p = q->Next;
    

    由于q 没有移动,这只会导致在每次迭代中将相同的值分配给p。这样做会更有意义q = q-&gt;Next

  • 您的代码没有正确分离要删除的节点。它只是结束列表:

    p->Next = NULL;
    

    这没有考虑到p 之前的节点仍在引用p。实际上,需要重新布线的是 前面的节点。所以你实际上希望前面的循环提前一步停止,所以你有前面的节点q的引用,然后这样做:

    p = q->Next; // p will be deleted
    q->Next = p->Next; // Rewiring around p
    

这里是更正后的main

int main() {
    int n, m, i;
    PtrToNode head, p, q;

    printf("Please input n, m\n");
    scanf("%d %d", &n, &m);
    printf("Input was n=%d, m=%d\n", n, m);

    head = (PtrToNode)malloc(sizeof(struct Node));
    head->num = 1;

    p = head;
    for (i = 2; i <= n; i++) {
        q = (PtrToNode)malloc(sizeof(struct Node));
        q->num = i;
        p->Next = q;
        p = q;
    }
    p->Next = head;

    while (q->Next != q) {
        for (i = 1; i < m; i++)
            q = q->Next;
        p = q->Next;
        printf("%d, ", p->num);
        q->Next = p->Next;
        free(p);
    }
    printf("%d\n", q->num);
    free(q);
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-22
    • 1970-01-01
    • 2020-12-10
    • 2019-07-21
    相关资源
    最近更新 更多