猴子选王)约瑟夫环方法4种方法之一——数组链接方式实现

代码

#include  <stdio.h>
int main()
{
	int n, m;   //猴子个数,报数到m退出
	int number;//记录猴子实际个数
	int count;//为当前循环做准备
	int i, pos, prior;//pos>prior
	int monkey[301] = { 0 };

	int monkey[301] = { 0 };//数组存储下一个猴子的位置,标识为-1的为淘汰
//初始化数组,数组存储下一个猴子的下标





	while (~scanf_s("%d%d", &n, &m))
	{
		if (n == 0 || m == 0)
		{
			return 0;
		}
		else
		{

			for (i = 0; i < n - 1; i++)              //初始化数组
			{
				monkey[i] = i + 1;
			}
			monkey[i] = 0;//下标为n-1的元素的下个序号为0,形成循环链表

			number = n;
			pos = 0;
			prior = n - 1;
			count = 1;
			while (number > 1)                     //淘汰对应间隔元素
			{
				if (count != m)                     //不到淘汰位置
				{
					prior = pos;
					pos = monkey[pos];                 //数组链表循环时关键步骤
					count++;
				}
				else                                   
				{ //更改链接关系
					monkey[prior] = monkey[pos];//为以后pos(假指针位移做准备)。
					monkey[pos] = -1;//表示淘汰
					pos = monkey[prior];//移动到淘汰位置的下一个
					//然而prior还是在pos的前一个,只要接下来循环链接过程还是以prior = pos;
																		  /*pos = monkey[pos];
																		   而不是prior++的形式就行。
						*/
					number--;       //
					count = 1;
				}
				错误示范,注意事项
				//	monkey[prior - 1] = monkey[prior];   //注意关系monkey【prior】里面的值比prior大一,pos同理
				//	  //所以不应该存在 在淘汰循环前一个的赋值。无意义


				//	monkey[prior] = -1;//淘汰位置出错
				//	prior = monkey[prior];
				//	pos = monkey[pos];
				//	count = 1;

			}
			printf("%d\n",pos+1);//不能用monkey【pos】,因为可能里面的元素已经被改过了
                                                          //monkey[prior] = monkey[pos]; 
                                                             // (改变情况)
		}

		
	}
return 0;
}

 关于初始化中数组如何模拟循环链表的问题

 

 相当于最后一个元素的monkey【pos】等于第一个元素的pos。

            在没有循环删除前  monkey【pos】等于pos+1

                                   monkey【prior】等于prioe+1

          循环删除后数组里的元素可能发生错乱。

for (i = 0; i < n - 1; i++)              //初始化数组
			{
				monkey[i] = i + 1;
			}
			monkey[i] = 0;//下标为n-1的元素的下个序号为0,形成循环链表

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值