C语言:选老大游戏

选老大。N个游戏者围成一圈,从第一个人开始顺序报数1,2,3。凡报道3者退出圈子,最后留在圈中的人为首领。

思路

创建一个包含N个结点的单循环链表来模拟N个人围成的圈,如下图所示。其中结点的数据域存放游戏者的编号,该链表不设头结点,头指针为head。
在这里插入图片描述
在程序中,以删除结点代表人退出圈子,设置整形变量c用于计数,指针变量开始时指向head。p每向后一个结点,c加1。当c=2时,就删除下一个结点(报道3者退出圈子)。如下图
在这里插入图片描述
代码如下:

#include "pch.h"
#include <iostream>
#include<stdlib.h>
typedef struct node {
	int id;		/*游戏者的编号*/
	struct node*next;
}NODE, *LinkList;

LinkList create_list(int n)
/*创建一个节点数为n的单循环链表,返回值为游戏编号为1的结点的指针*/
{
	LinkList head, p;
	int k;
	head = (NODE*)malloc(sizeof(NODE));/*创建循环列表的第一个结点*/
	if (!head) {
		printf("memory allocation error!\n"); return NULL;
	}
	head->id = 1; head->next = head;
	for (k = n; k > 1; --k) {/*尾插法创建循环链表的其余n-1个结点*/
		p = (NODE*)malloc(sizeof(NODE));
		if (!p) {
			printf("memory allocation error!\n"); return NULL;
		}
		p->id = k; p->next = head->next; head->next = p;
	}
	return head;
}

void play(LinkList head, int n)
{
	LinkList p, s;
	int c = 0, k;
	p = head; c = 1; k = n;
	while (k>1)
	{
		if (c == 2)	/*当c等于2时,p指向的结点的后继即为将被删除的结点*/
		{
			s = p->next; p->next = s->next;
			printf("%4d", s->id); free(s);
			c = 0; k--;
		}
		c++; p = p->next;
	}
	printf("\n%4d was the winner,", p->id);		/*输出最后留在圈子内的游戏者编号*/
}

void output(LinkList head)		/*输出链表中结点的数据*/
{
	LinkList p;
	p = head;
	do {
		printf("%4d", p->id); p->next;
	} while (p != head);
	printf("\n");
}

int main()
{
	LinkList headptr;
	int n;
	printf("input the number of players:"); scanf_s("%d", &n);
	headptr = create_list(n);		/*创建单循环列表*/
	if (headptr) {
		output(headptr);		/*输出单循环列表中的结点的信息*/
		play(headptr, n);
	}
	return 0;
}

运行结果:
在这里插入图片描述
游戏结束时,链表还有一个节点,这就是老大!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值