#include<stdio.h>
#include<stdlib.h>
//使用循环链表实现约瑟夫化
//定义节点的数据结构
typedef struct Node{
char data;
struct Node* next;
}node, *linkNode;
void InitCircularTable(linkNode *head,int *w,int n){
int i;
//分配指向该链表的内存
linkNode p,temp;
*head = (linkNode)malloc(sizeof(node));
p = *head;
p->data = w[0];
p->next = *head;
for(i=2; i<= n; i++){
temp = (linkNode)malloc(sizeof(node));
(temp)->data = w[i-1];
p ->next = temp;
(temp)->next = *head;
p = temp;
}
}
//开始游戏,startIndex:开始报名的位位置,number:报数,遇到该数人出局,并归零
void StartGame(linkNode head,char startperson,int number){
int k;
linkNode temp;
//遍历寻找开始者的位置
while(head ->next !=head){
if(head->data == startperson){
//开始游戏,跳出条件只有一个参与者
//如何能记住上一个参与者
k =1;
while(head ->next !=head){
temp= head;
head = head->next;
k++;
if(k == number){
//出局
printf("出局者: %c \n",head->data);
k=0;
//将该人删除
temp->next = head->next;
}
}
printf("胜利者为:: %c \n",head->data);
break;
}
head = head->next;
}
}
//打印
void print(linkNode head){
linkNode p;
p= head;
printf("%c ",head->data);
while(head->next != p){
head = head->next;
printf("%c ",head->data);
}
printf("\n");
}
int main(){
int w[5] = {'a','b','c','d','e'};
linkNode head;
InitCircularTable(&head,w,5);
print(head);
StartGame(head,'c',3);
}
结果:
第二种:递归和非递归思想
#include<stdio.h>
#include<stdlib.h>
//采用数组实现
#define MAXSIZE 20
//使用链表实现约瑟夫环
typedef struct Node{
int data;
struct Node* next;
}LinkNode;
//初始化数组
void InitArr(int *Arr, int m){
int i=0;
while(m>=0){
Arr[i] = i;
i++;
m--;
}
}
//利用数组开始游戏
void StartKing(int* Arr, int n,int m){
int Deletecount=0; //删去的人数
int k=0;
int i = 1,j=1;
int len ;
while(Deletecount < m-1){
for(i = 1;i<=m; i++){
if(Arr[i] != 0){
k++;
if(k== n){
Arr[i] = 0;
k=0;
printf("%d is the deleteData\n", i);
Deletecount++;
}
}
}
}
//还剩一个人
//打印国王
while(Arr[j] ==0){
j++;
}
printf("%d is the King!",j);
}
//初始化链表
LinkNode* Init(LinkNode* head, int m){
int i=1;
LinkNode* p;
LinkNode* temp;
head = (LinkNode*)malloc(sizeof(LinkNode));
if(head ==NULL){
exit(0);
}
p= head;
head->data = 1;
head->next = NULL;
while(i<m){
temp = (LinkNode*)malloc(sizeof(LinkNode));
temp->data = i+1;
temp->next = NULL;
head->next = temp;
head = temp;
i++;
}
//循环链表
temp->next = p;
return p;
}
//开始游戏,使用循环链表
void startKing(LinkNode* head,int n){
//计数器
int count = 0;
LinkNode* pre = head;
LinkNode* temp = head;
//终止条件,只剩下一个人
//需要一个新节点,记住删除节点的上一个节点
while(pre->next != pre){
count++;
if(count == n){
//删除节点
temp->next = pre->next;
count=1;
printf("%d is the deleteData\n", pre->data);
free(pre);
pre = temp->next;
}
temp = pre;
pre = pre->next;
}
printf("%d is the King!\n", pre->data);
}
int main(){
int m,n;
int Arr[MAXSIZE]={0};
LinkNode* head= NULL;
printf("请输入m和n的值:");
scanf("%d %d",&m,&n);
head = Init(head,m);
startKing(head,n);
InitArr(Arr,m);
StartKing(Arr,n,m);
return 0;
}
结果: