问题描述:
刚学数据结构的时候,我们可能用链表的方法去模拟这个过程,N个人看作是N个链表节点,节点1指向节点2,节点2指向节点3,……,节点N - 1指向节点N,节点N指向节点1,这样就形成了一个环。然后从节点1开始1、2、3……往下报数,每报到M,就把那个节点从环上删除。下一个节点接着从1开始报数。最终链表仅剩一个节点。它就是最终的胜利者。
举例:某天你去原始森林玩,碰到了一群土著邀请你去玩一个杀人游戏8个人围坐一圈,报数,报到3的人拿根绳吊死,问如何保命,笑到最后
思路分析:
初始时刻,头指针指向1所在的节点每隔2个节点,删除一个节点,需要注意的是删除节点前,要记录下一个节点的位置,所以要定义两个指针变量,一个指向当前节点,另一个指向当前节点的前一个节点,删除节点节点前,记录要删除节点的下一个节点的位置删除节点后当前节点指向删除节点的下一个节点该问题可以抽象为一个无头节点单向循环链表,链表中有8个节点,各节点中依次填入数据1,2,3,4,5,6,7,8
prenode->next = curnode->next;printf("%d\t", curnode->data);free(curnode);curnode = prenode->next;
完整代码
main.c(用于测试)
#include<stdio.h>#include<stdlib.h>#include "list.h"int main(){struct node_st *list = NULL,*lastnode =NULL;list=list_create(SIZE);list_show(list);list_kill(&list, STEP);list_show(list);return 0;}
list.c(用于函数定义)
#include<stdio.h>#include<stdlib.h>#include "list.h"//约瑟夫环可以使用无头节点,单向循环链表来表示struct node_st* list_create(int n){int i = 1;struct node_st* p = NULL;struct node_st* ps = NULL;struct node_st* q = NULL;p = (struct node_st*)malloc(sizeof(struct node_st));if (p == NULL){return NULL;}p->data = i;p->next = p;i++;//定义一个结构体变量,记录约瑟夫环起始位置ps = p;while (i <= n){q = (struct node_st*)malloc(sizeof(struct node_st));if (q == NULL){return NULL;}q->data = i;q->next = ps;p->next = q;p = q;i++;}return ps;}void list_show(struct node_st* ps){//一般来讲,我们不移动头指针ps,而是移动ps的拷贝,原因://出错时方便调试以及头指针位置不丢失struct node_st* p = NULL;for (p = ps; p->next != ps; p = p->next){printf("%d\t", p->data);}printf("%d\n", p->data);}void list_kill(struct node_st** ps,int n){struct node_st *prenode = NULL;struct node_st *curnode = *ps;int i = 0;while (curnode != curnode->next){//每轮删除,隔n-1个节点,删除一个节点while (i < n - 1){prenode = curnode;curnode = curnode->next;i++;}prenode->next = curnode->next;printf("%d\t", curnode->data);free(curnode);curnode = prenode->next;i = 0;}*ps = curnode;printf("\n");}
list.h(负责函数声明)
#ifndef LIST_H__#define LIST_H__#define SIZE 8#define STEP 3struct node_st{int data;struct node_st *next;};//约瑟夫环的创建struct node_st* list_create(int n);//约瑟夫环的展示void list_show(struct node_st*ps);//约瑟夫环删除节点void list_kill(struct node_st** ps,int n);#endif
如果觉得《约瑟夫环(杀人游戏)》对你有帮助,请点赞、收藏,并留下你的观点哦!