问题描述:
- 魔术师利用一副牌中的13张黑桃牌,预先将他们排好后叠放在一起,牌面朝下。对观众说:“我不看牌,只数数就可以猜到每张牌是什么,我大声数数,你们听,不信?现场演示。”魔术师将牌堆最上面的哪张排数为1,把他翻过来正好是黑桃A,将黑桃A从牌堆抽出放在桌子上,第二次数1、2,将第一张放在牌堆最下面,第二张翻开,正好是黑桃2,也将它抽出放在桌子上。这样依次进行将13将牌全部翻出,准确无误。问牌最开始的顺序是怎样排的。
简单点说:把13张牌按照一定的顺序排好,然后依次取牌,将每次取到的牌放在最下面,情形如下:
数一次,取牌,黑桃1,放牌堆最下面
数两次,取牌,黑桃2,放牌堆最下面
数三次,取牌,黑桃3,放牌堆最下面
数四次,取牌,黑桃4,放牌堆最下面
…直到取到最后的黑桃13(黑桃K),表演结束!
通过问题我们可以发现这是典型的约瑟夫问题的逆运算,因此我们可以用循环链表来解决。
思路:用循环链表模拟魔术师取出牌的过程,最后从头到位输出即可。
1 0 0 0 0 0 0 0 0 0 0 0 0
1 0 2 0 0 0 0 0 0 0 0 0 0
1 0 2 0 0 3 0 0 0 0 0 0 0
1 0 2 0 0 3 0 0 0 4 0 0 0
1 0 2 5 0 3 0 0 0 4 0 0 0
1 0 2 5 0 3 0 0 0 4 0 6 0
1 0 2 5 0 3 0 0 0 4 7 6 0
1 8 2 5 0 3 0 0 0 4 7 6 0
1 8 2 5 0 3 0 0 9 4 7 6 0
1 8 2 5 10 3 0 0 9 4 7 6 0
1 8 2 5 10 3 0 11 9 4 7 6 0
1 8 2 5 10 3 12 11 9 4 7 6 0
1 8 2 5 10 3 12 11 9 4 7 6 13
1 8 2 5 10 3 12 11 9 4 7 6 13
代码:
#include <stdio.h> #include <malloc.h> typedef struct node{ int id; struct node * next; }Node,*LinkList; void addNode(LinkList * linkList,int id); void traverse(LinkList * linkList,void (*pfun)(int)); void initLinkList(LinkList * linkList); void pfun(int data) ; int main(void) { LinkList linkList = NULL; initLinkList(&linkList); int i,k; for(i=0;i<13;i++) addNode(&linkList,0);//生成13个节点并将值初始化为0 Node * pn = linkList; Node * temp; for(i=0;i<13;i++) { k = 0; while(k<i+1) { pn = pn->next; if(pn->id == 0 && pn != linkList) { k++; } } pn->id = i+1; traverse(&linkList,pfun); printf("\n"); } traverse(&linkList,pfun); pn = linkList; while(pn->next != linkList) { temp = pn->next; pn = pn->next; free(temp); } free(linkList); return 0; } void pfun(int data) { printf(" %d",data); } void initLinkList(LinkList * linkList) { (*linkList) = (Node *)malloc(sizeof(Node)); (*linkList)->next = *linkList; } //头插法添加元素 void addNode(LinkList * linkList,int id) { Node * pn = (Node *)malloc(sizeof(Node)); pn->id = id; if(!(*linkList)->next) { pn->next = *linkList; }else{ pn->next = (*linkList)->next; } (*linkList)->next = pn; } void traverse(LinkList * linkList,void (*pfun)(int)) { Node * pn = (*linkList); while(pn->next != *linkList) { pfun(pn->next->id); pn = pn->next; } }
代码运行结果: