C语言实现约瑟夫环

直接上代码

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

typedef struct ListNode
{
	int data;
	struct ListNode * next;
}ListNode;

void create(ListNode * firstNode, int m) //创建单向循环链表
{
	if (firstNode == NULL)
	{
		return;
	}

	int i;
	ListNode * pre = firstNode;
	for (i = 2; i <= m; i++)
	{
		ListNode * node = (ListNode *)malloc(sizeof(ListNode));
		node->data = i;
		pre->next = node; //让前一个节点的next域为刚刚生成的node的地址
		pre = node;
	}
	pre->next = firstNode;
}

void show(ListNode * firstNode) //显示循环链表的节点编号
{
	if (firstNode == NULL)
	{
		return;
	}
	int i;
	printf("创建的单向环表节点编号依次为:\n");

	ListNode * p = firstNode;
	printf("%d\n", p->data);
	p = p->next;
	while (p != firstNode)
	{
		printf("%d\n", p->data);
		p = p->next;
	}
}

ListNode * joseph(ListNode * firstNode, int m, int s, int n) //一共m个结点, 从第s个结点开始计数到第n个结点
{
	if (firstNode == NULL || s > m || s < 1)
	{
		return;
	}
	
	int i;
	ListNode * current = firstNode;
	for (i = 1; i <= s-1; i++)
	{
		current = current->next;
	}

	printf("输出第s个结点:\n");
	printf("%d\n", current->data);

	int j;
	for (j = 2; j <= n-1; j++) //current已经为当前节点,所以j从2开始(下一个节点)
	{
		current = current->next; //走到第n个结点的前一个节点
	}
	printf("输出第n个结点:\n");
	printf("%d\n", current->next->data);

	//删除第n个结点
	ListNode * nodeN = current->next;
	current->next = nodeN->next;
	
	if (nodeN == firstNode)
	{
		firstNode = nodeN->next;
	}

	nodeN->next = NULL;
	free(nodeN);

	show(firstNode);
	
	return firstNode;
}

int main()
{
	int m, s, n, r; //从第s个结点开始计数到第n个结点
	printf("输入单向环表节点数m:\n");
	scanf("%d", &m);
	printf("输入开始计数的节点编号s:\n");
	scanf("%d", &s);
	printf("输入计数到的节点编号n:\n");
	scanf("%d", &n);

	ListNode * firstNode = (ListNode *)malloc(sizeof(ListNode));
	firstNode->data = 1;
	create(firstNode, m);
	show(firstNode);
	firstNode = joseph(firstNode, m, s, n);
	show(firstNode);

	return 0;
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值