C语言实现Josephus问题:双向循环链表应用

本代码使用C语言实现Josephus问题,并使用双向循环链表来存储和操作参与者信息。

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

// 定义双向循环链表节点结构
typedef struct Node {
    int data;
    struct Node* prev;
    struct Node* next;
} Node;

// 创建一个新的节点
Node* createNode(int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->prev = NULL;
    newNode->next = NULL;
    return newNode;
}

// 在链表中插入一个节点
void insertNode(Node** head, Node* newNode) {
    if (*head == NULL) {
        *head = newNode;
        newNode->prev = newNode;
        newNode->next = newNode;
    }
    else {
        Node* tail = (*head)->prev;
        newNode->next = *head;
        newNode->prev = tail;
        tail->next = newNode;
        (*head)->prev = newNode;
    }
}

// 从链表中删除一个节点
void deleteNode(Node** head, Node* node) {
    if (*head == NULL || node == NULL) {
        return;
    }

    if (*head == node) {
        if ((*head)->next == *head) {
            *head = NULL;
        }
        else {
            *head = node->next;
        }
    }

    node->prev->next = node->next;
    node->next->prev = node->prev;
    free(node);
}

// 解决Josephus排列问题
void josephus(int n, int m) {
    Node* head = NULL;

    // 创建链表并初始化
    for (int i = 1; i <= n; i++) {
        insertNode(&head, createNode(i));
    }

    Node* current = head;
    int count = 1;

    while (head != NULL) {
        if (count % 2 == 1) {
            for (int i = 1; i < m; i++) {
                current = current->next;
            }
        }
        else {
            for (int i = 1; i < m; i++) {
                current = current->prev;
            }
        }

        printf('%d ', current->data);

        Node* next = (count % 2 == 1) ? current->next : current->prev;
        deleteNode(&head, current);
        current = next;
        count++;
    }
}

int main() {
    int n, m;
    printf("请输入竞赛者数量n:");
    scanf_s("%d", &n);
    printf("请输入计数值m:"); 
    scanf_s("%d", &m);

    printf("Josephus排列结果为:");
    josephus(n, m);
    printf("\n");

    return 0;
}

代码分析:

  1. 双向循环链表: 代码使用双向循环链表存储参与者信息,方便进行顺时针和逆时针的遍历。
  2. 节点操作: 包含创建节点、插入节点、删除节点等基本操作,为解决Josephus问题提供基础。
  3. Josephus排列: 代码模拟了Josephus问题的过程,通过循环遍历链表并删除特定节点的方式,最终输出Josephus排列结果。

代码的优点:

  • 逻辑清晰,注释详细,易于理解。
  • 使用双向循环链表,高效地实现了顺时针和逆时针遍历。
  • 能够正确输出Josephus排列结果。

改进建议:

  • 可以增加更多测试用例,验证代码的正确性。
  • 可以将代码封装成函数,使其更加模块化,便于复用。
  • 可以使用更简洁的代码风格,提高代码可读性。

总结:

本代码展示了利用双向循环链表解决Josephus问题的过程,体现了对链表结构的应用和对问题的分析能力。同时,代码也展示了良好的编程风格和注释习惯。通过不断改进,可以将代码优化得更加完善。

C语言实现Josephus问题:双向循环链表应用

原文地址: https://www.cveoy.top/t/topic/bmdf 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录