当前位置:首页C语言 > 正文

C语言约瑟夫问题(约瑟夫环)

作者:野牛程序员:2023-08-23 11:32:46C语言阅读 3360

约瑟夫问题,又称约瑟夫环,是一个经典的数学问题,涉及到一个环形队列,每次从队列中删除第 m 个人,直到队列中只剩下一个人。下面是用 C 语言解决约瑟夫问题的示例代码:

#include <stdio.h>
#include <stdlib.h>

// 定义链表节点
typedef struct Node {
    int data;
    struct Node *next;
} Node;

// 创建一个具有 n 个节点的循环链表
Node* createCircularLinkedList(int n) {
    Node *head = NULL;
    Node *prev = NULL;
    
    for (int i = 1; i <= n; i++) {
        Node *newNode = (Node *)malloc(sizeof(Node));
        newNode->data = i;
        
        if (head == NULL) {
            head = newNode;
        } else {
            prev->next = newNode;
        }
        
        newNode->next = head;
        prev = newNode;
    }
    
    return head;
}

// 在循环链表中删除第 m 个节点
Node* removeMthNode(Node *head, int m) {
    if (head == NULL) {
        printf("链表为空\\n");
        return NULL;
    }
    
    Node *current = head;
    Node *prev = NULL;
    
    // 移动到待删除节点的前一个节点
    for (int i = 1; i < m; i++) {
        prev = current;
        current = current->next;
    }
    
    // 删除节点
    if (prev != NULL) {
        prev->next = current->next;
    } else {
        head = current->next;
    }
    
    printf("出列的编号:%d\\n", current->data);
    free(current);
    
    return head;
}

int main() {
    int n, m;
    printf("请输入总人数 n 和每次删除的第 m 个人:");
    scanf("%d %d", &n, &m);
    
    Node *head = createCircularLinkedList(n);
    
    while (head != head->next) {
        head = removeMthNode(head, m);
    }
    
    printf("最后留下的人的编号:%d\\n", head->data);
    
    free(head);
    
    return 0;
}

这段代码首先创建了一个循环链表,表示人们围成的环。然后,根据输入的每次删除第 m 个人,逐步移除节点,直到链表中只剩下一个节点为止,即找到了最后留下的人。请注意,这只是一个基本示例,实际应用中可能需要更多的错误检查和优化。


野牛程序员教少儿编程与信息学奥赛-微信|电话:15892516892
野牛程序员教少儿编程与信息学竞赛-微信|电话:15892516892
相关推荐

最新推荐

热门点击