- 问题描述:魔术师利用一副牌中的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);
}
- 测试,测试直接在单项循环链表中调用其方法即可,大家可以点击链接了解单向循环链表的实现过程已经测试类https://blog.csdn.net/qq_44941119/article/details/100868410
loop.mginPoker();
运行结果: