(C语言)链表实现约瑟夫环

关键:结束条件为当p->next == p,此时说明链表只剩下该结点了。 

#include<stdio.h>
#include<stdlib.h>
typedef struct Lnode{
	int data;
	struct Lnode* next;
}Pnode;

Pnode* createnode(int n)
{
	Pnode* head = (Pnode*)malloc(sizeof(Pnode));
	head->data = 1;
	head->next = NULL;
	Pnode* r = head;
	for(int i=2; i<=n; i++)
	{
		Pnode* s = (Pnode*)malloc(sizeof(Pnode));
		s->data = i;
		s->next = NULL;
		r->next = s;
		r = s;
	}
	r->next = head;
	return head;
}

void findandkill(Pnode* head, int m)
{
	Pnode* tail = head;
	while(tail->next != head)
	{
		tail = tail->next;
	}
	Pnode* p = head;
	while(p->next != p)
	{
		for(int i=1; i<m; i++)//本题1 2进循环 3不进入循环 第三个被删掉 
		{
			tail = p;
			p = p->next;
		}
		tail->next = p->next;
		free(p);
		p = tail->next;
	}
	printf("%d",p->data);
	free(p);
}
int main()
{
	int n, m;
	scanf("%d%d",&n,&m);
	Pnode* head = createnode(n);
	findandkill(head, m);
	return 0;
}

还有一个知识点:链表结点的删除:

for(int i=1; i<m; i++)
{
		{
			tail = p;
			p = p->next;//找到两个一前一后的指针
		}
		tail->next = p->next;//将前一个指针指向后一个指针原本指向的位置,即前一个结点跳过了后一个结点和第三个结点相连了
		free(p);//记得将跳过的那个结点内存清除
		p = tail->next;//再次将两个结点回归一前一后的关系
}
	

利用链表思想,用数组实现:(理解)

#include<stdio.h>
int main()
{
	int n,m;
	printf("请输入有多少个人n:\n");
	scanf("%d",&n);
	printf("请输入淘汰数m:\n");
	scanf("%d",&m);
	
	int L[10000];///数组的长度为题目定的最大值
	int i,j; 
	for (i=0;i<n;i++)
	{
		L[i]=i+1;
	}
	L[n-1]=0;//1 2 3 ... n-1 0
	
	int cnt=n,count=1;
	int p=0,q=0;
	p=L[p];//p = 1
	
	while(cnt!=1)
	{
		if (count%m==0)
		{
			L[q]=L[p];
			printf("淘汰的人为:%d\n",p);
			cnt--;
		}
		q=p;
		p=L[p];
		count++;
	}
	
	if (L[p]==0)
	printf("剩下的人:%d",n);
	else
	printf("剩下的人:%d",L[p]);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值