数据结构实验一约瑟夫环

采用单向环表实现约瑟夫环。

请按以下要求编程实现:

  • 从键盘输入整数m,通过create函数生成一个具有m个结点的单向环表。环表中的结点编号依次为1,2,……,m。
  • 从键盘输入整数s(1<=s<=m)和n,从环表的第s个结点开始计数为1,当计数到第n个结点时,输出该第n结点对应的编号,将该结点从环表中消除,从输出结点的下一个结点开始重新计数到n,这样,不断进行计数,不断进行输出,直到输出了这个环表的全部结点为止。

例如,m=10,s=3,n=4。则输出序列为:6,10,4,9,5,2,1,3,8,7。

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

struct Node // 结点定义
{
    int order;         // 序号
    struct Node *next; // 下一个结点的指针
};
typedef struct Node Node;

Node *InitLIst() // 初始化环
{
    Node *Head = (Node *)malloc(sizeof(Node));
    Head->order = 1;
    Head->next = Head;
    return Head;
}

void Creat(Node *Head, int m) // 创建结点
{
    int i;
    Node *current = Head;
    for (i = 2; i < m + 1; i++)
    {
        Node *p = (Node *)malloc(sizeof(Node));
        p->order = i;
        p->next = Head;
        current->next = p;
        current = p;
    }
}

Node *Del(Node *Head, Node *current) // 删除结点
{
    Node *p = Head;
    if (Head->next == Head) // 如果只剩一个结点,直接删除
    {
        free(Head);
        return NULL;
    }
    while (p->next != current) // 让p指向删除结点的前一个结点
    {
        p = p->next;
    }
    p->next = current->next;
    if (Head == current) // 如果删除的是头结点,需要更新头结点
    {
        Head = p->next;
    }
    free(current);
    return p->next;
}

int main()
{
    int m, s, n, count;
    int flag = 1;
    Node *Head = InitLIst(); // 初始化环
    Node *current = Head;
    scanf("%d %d %d", &m, &s, &n); // 获取输入
    Creat(Head, m);                // 创建完整的环
    for (int i = 1; i < s; i++)     //使current到达第s个结点
    {
        current = current->next;
    }
    count = 1;
    while (flag)
    {
        if (n != 1)         //如果n不为1,则需要计数,n为1,直接逐个输出
        {
            current = current->next;
            count++;
        }
        if (count == n)
        {
            printf("%d\n", current->order);
            Node *nextNode = Del(Head, current);
            if (current == Head)    //如果当前结点是头结点,需要更新头结点
            {
                Head = nextNode;
            }
            current = nextNode;
            if (current == NULL)    //当前结点为空,停止循环
            {
                flag = 0;
                break;
            }
            count = 1;
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值