单向循环链表经典问题——问题三:魔术师发牌问题

  • 问题描述:魔术师利用一副牌中的13张黑牌,预先将它们排好后叠放到一起,牌面朝下。对观众说:”我不看牌,只数数就可以猜到每张牌是什么,我大声数,你们听,不信?现场演示。“魔术师将最上面的那张牌数为1,把他翻过来正好是黑桃A1,将黑桃A放到桌子上,第二次数1,2,将第一张牌放在这些牌的下面,将第二张牌翻过来,正好时黑桃2,也将他放在桌子上这样依次进行将13张牌全部翻出,准确无误。

问题:牌的最开始顺序是什么?

  • 解题思路:很明显这也是一个单向循环链表的问题,总共13张牌,我们可以模拟一下这个过程,先画13个框,然后数1将第一张牌放进去,接着数1,2将第二张牌放进去,依次类推,我们先来看看图再来想代码怎样去实现,一般数据结构的问题我们需要借助图来深刻理解题的思路,所有会画图很重要的

       黑桃A进来放到第一个位置

      然后从第二个位置开始数1,2,当然会在数到2的位置上放黑桃2

      再接着从黑桃2后面那个位置数1,2,3,3的位置放黑桃3

       以此类推,直至放黑桃5的时候出现了特殊情况,需要注意啦,各位小可爱们

       当我们已经将黑桃4放进来之后,在放黑桃5的时候我们会发现当数到4的时候是我们放黑桃A的地方(循环链表),那么黑桃5是放到黑桃A后面的的位置吗?当然不是了,你在想什么?坑都被人家早都占了,你还能挤走人家?所有当遇到这种已经有牌的地方我们的数字不算数继续往下数,也就是说数到黑桃A为4的这个时候4失效了,需要重新往下数,那么如果往下数还有没有坑,那么就一直失效,直至找到属于你的坑

       我们就这样一次次往下数,然后就可以把每张牌都成功放进自己的坑里了

 

     到了这里,你的思路是不是很清晰啦!由此可见我们这个题是添加元素,而且要注意的是我们已经添加过的地方必须得跳过,在添加牌得过程中我们是先把放这13张牌得位置准备好,然后将牌放进去,这样我们可以保证其连续得关系,那么我就直接上代码啦!因为我们这个方法也是在单项循环链表中写的,所以我们可以直接调用单项循环链表中的方法。

 public void mginPoker() {
	  head=null;
	  rear=null;
	  size=0;
	  for(int i=0;i<13;i++) {  //建立13个“坑”用来存放13张牌
		  addLast((E) new Integer(0)); 
	  }
	  Integer pokerNumber=1; //记录牌数
	  Node p=rear; //p从尾开始
	  while(true) {
		  for(int i=0;i<pokerNumber;) { 
			  p=p.next;
			  if(p.data.equals(0)) {
				 i++; 
			  }
		  }
         p.data=(E) pokerNumber;//将牌放进指针所指向的结点
         pokerNumber++;   //牌数增加
         if(pokerNumber.equals(14)) {//如果牌数等于14的时候跳出循环,因为只要13张牌
        	 break;
         }
	  }
	  System.out.println(this);
  }
loop.mginPoker();

  运行结果:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值