学习笔记之约瑟夫环的两种实现方法(数组&链表)
2015-04-08 23:12
866 查看
传说在很久很久以前,罗马人占领乔塔帕特之后咱们的约瑟夫大大,哦不,是著名的犹太历史学家约瑟夫(Josephus)和他的朋友躲在一个洞中,当时洞中还有其他的39名犹太人,他们非常的傻(ai)逼(guo),宁愿死也不要被俘虏,于是非常聪明的想出一个绝世妙计来进行车轮式自杀。他们手拉手围成一个圈,从第一个人开始报数,谁报到3就自杀,然后下一个人继续从1开始报数直到所有的人都自杀完。。。。然而约瑟夫大大和他的朋友不想就这样无缘无故的死去,于是把自己和朋友安排在第16个位置和第31个位置成功地躲过了一劫。。。
那么。。。问题来了,我们怎样用程序来把自杀的顺序排出来呢??
(ps:代码仅用来实现功能而并未优化。)
思路一:
定义一个数组用下标来代表每一个人,初始化为0,用0来代表他们活着,1代表死亡,当数到他时就将他杀掉(内容置为1)并将下标输出来,最后输出所有的元素下标后程序结束。
创建一个循环链表,把它的首节点和尾节点连起来,就像约瑟夫大大和他的基(nan)友们一样手牵手围成一个圈,然后数到一个就将一个free(杀)掉并将它数据域内的编号取出来直到所有基(nan)友被杀光时程序结束。
那么。。。问题来了,我们怎样用程序来把自杀的顺序排出来呢??
(ps:代码仅用来实现功能而并未优化。)
思路一:
定义一个数组用下标来代表每一个人,初始化为0,用0来代表他们活着,1代表死亡,当数到他时就将他杀掉(内容置为1)并将下标输出来,最后输出所有的元素下标后程序结束。
#include <stdio.h> #include <malloc.h> int main(void) { int m,i,cnt,j = 1,k = 0; int *pArr; printf("n = "); //总个数输入提示 scanf("%d",&cnt); //输入总个数 printf("m = "); //数到m时自杀 scanf("%d",&m); //输入m pArr = (int *)malloc(cnt * sizeof(int)); for (i = 0;i < cnt;i++) { pArr[i] = 0; //初始化为0 } i = 0; while(1) { if (i < cnt && 0 == pArr[i]) //i小于总个数且值为0(活着) { if (m == j) { pArr[i] = 1; //置为1(杀掉) j = 0; printf("%d\t",i+1);//输出该人编号(因为下标是从0开始,所以是输出i+1而非i) k++; if (k == cnt) break; } j++; } else if(i == cnt) i = -1; i++; } printf("\n"); return 0; }思路二 :
创建一个循环链表,把它的首节点和尾节点连起来,就像约瑟夫大大和他的基(nan)友们一样手牵手围成一个圈,然后数到一个就将一个free(杀)掉并将它数据域内的编号取出来直到所有基(nan)友被杀光时程序结束。
#include <stdio.h> #include <malloc.h> typedef struct node { int no; struct node *pNext; }NODE; //创建长度为n的链表 NODE *create(int n) { NODE *pHead,*pTail,*pNew; int i; pHead = (NODE *)malloc(sizeof(NODE)); pTail = pHead; for (i = 1;i <= n;i++) { pNew = (NODE *)malloc(sizeof(NODE)); pTail->pNext = pNew; pNew->no = i; pTail = pTail->pNext; } pTail->pNext = pHead->pNext; return pHead; } //打印第pos个元素的数据域并删除,pos从1开始 void pop(NODE *pHead,int pos) { NODE *pPos,*pTemp; int i; pPos = pHead; for (i = 1;i < pos;i++) pPos = pPos->pNext; pTemp = pPos->pNext->pNext; printf("%d\t",pPos->pNext->no); free(pPos->pNext); pPos->pNext = pTemp; } int main(void) { NODE *pHead,*pTemp; int n,m,i,k; printf("n = "); scanf("%d",&n); if (n > 0) { pHead = create(n); printf("m = "); scanf("%d",&m); pTemp = pHead; k = n; while(k) { for (i = 1;i < m;i++) pTemp = pTemp->pNext; pop(pTemp,1); k--; } printf("\n"); } else printf("输入有误!\n"); return 0; }欧了,丢手绢游戏至此结束
相关文章推荐
- 学习笔记之约瑟夫环的两种实现方法(数组&链表)
- 约瑟夫环问题的两种实现[链表+数组]
- 学习笔记:自定义方法的两种实现方式
- Android开发学习笔记(四):两种方法实现图片播放器
- C语言,数组实现约瑟夫环问题(两种方法)
- 两种方法实现约瑟夫环(链表,顺序表)
- 通过数组初始化链表的两种方法:指向指针的引用node *&tail和指向指针的指针(二维指针)node **tail
- 14. JAVA 枚举(Enum、类集EnumMap&EnumSet 、实现接口、定义抽象方法) ----- 学习笔记
- 线性表的两种实现方法-数据结构学习笔记2.1
- 通过数组初始化链表的两种方法:指向指针的引用node *&tail和指向指针的指针(二维指针)node **tail
- hz_meeting_学习笔记1_后台通讯·通用链表·结构体实现隐藏
- 递归求集合子集(两种方法实现(数组,链表))
- 播布客教学视频_C学习笔记_10.2_约瑟夫环问题(数组链表)
- @V@ java代码笔记2010-06-12:java控制台输入各类型类实现;以及判断输入字符串里面是否有数字的两种方法:方法1:转换成字符数组;方法2:正则表达式。
- 数据结构与算法学习笔记——链表部分实现(数组形式)
- Hibernate学习笔记之Session-API实现CRUD以及get&load&merge方法
- 堆栈的两种实现形式:数组和链表
- JNI学习笔记5——本地方法处理java数组/引用问题/缓存jfieldID/jmethodID
- 转:实例学习PHP程序对用户身份认证实现两种方法
- 链表反转的两种实现方法