已知 n 个人(以编号1, 2, 3 ,4, 5 ,6 ... .. .n)围坐一张圆桌周围。从编号为k 的人开始报数,数到m 的那个人出列;他的下一个人又从 1开始报数,数到m的那个人又出列;依次规律重复下去,直到圆桌周围的人全部出列。请用C++编程。
整个程序分为3个步骤:
第一步:建立一个有n个元素的循环链表,链表是从1的编号开始的。
第二步:是从链表的表头数到第 k 个值。
第三步:从 k 的后面开始输入 m 个值,删除该值,继续开始数,继续删。。。。。。。,直到删除完。
- #include <iostream>
- using namespace std;
- #define ERROR 0
- typedef struct LNode
- {
- int data;
- struct LNode *link;
- LNode()
- {
- data = 0;
- link = NULL;
- }
- }LNode,*LinkList;
- /************************************************************************/
- /* n 为总人数 */
- /* k 为第一个开始报数的人 */
- /* m为出列者喊到的数 */
- /************************************************************************/
- void Josephus(int n,int k,int m)
- {
- //pnode 为当前节点,secondnode为辅助节点,指向pnode的前驱节点,list为头结点
- if(n<0||k<0||m<0) return;
- LinkList pnode,prenode,curr;
- pnode = new LNode();
- pnode->data = 1;
- pnode->link = pnode; //建立一个循环链表
- curr = pnode;
- for (int i=2;i<=n;i++)
- {
- LinkList temp = new LNode();
- temp->data = i;
- temp->link = curr->link;
- curr->link = temp;
- curr = temp;
- }
- prenode = curr;
- while(k--)
- {
- prenode = pnode; //prenode是pnode的前一个结点。
- pnode = pnode->link; //移动结点 pnode是第k个元素
- }
- while(n--)
- {
- //for 是移动m个位置pnode是移动到的m位置,prenode是pnode的前一个结点
- for (int s=m;--s;prenode = pnode,pnode = pnode->link);
- prenode->link = pnode->link; //删除pnode结点
- printf("%d ",pnode->data); //打印删除的结点
- free(pnode); //释放空间
- pnode = prenode->link; //从prenode的下一个结点开始,数一个m个结点的值。
- }
- }
- void main()
- {
- Josephus(5,3,1);
- system("pause");
- }
运行的结果: