双向循环链表解决约瑟夫环(C语言)

第1题
在这里插入图片描述

#include<stdio.h>
#include <stdlib.h>

typedef struct student{
    
    
	int passwd;
	int id; 
	struct student* nextStudent;
	struct student* preStudent;
};

struct student* create(int n){
    
    
	//id从1开始 
	int nid = 1;
	
	printf("请依次输入密码\n");
	student* firstStudent = (student*)malloc(sizeof(student));
	firstStudent->id = nid++;
	scanf("%d",&firstStudent->passwd);
	student* lineNode = firstStudent;
	while(--n){
    
    //循环n-1次 
		student* tmpStudent = (student*)malloc(sizeof(student));;
		scanf("%d",&tmpStudent->passwd);
		tmpStudent->id = nid++;
		tmpStudent->preStudent = lineNode;
		lineNode->nextStudent = tmpStudent;
		lineNode = tmpStudent;//更新 
	}
	lineNode->nextStudent = firstStudent;//尾连接头,形成循环链表 
	firstStudent->preStudent = lineNode;//头连接尾,形成双向链表 

	return firstStudent;
} 

int* outputCirculationReportResult(int a[],int m,student* firstStudent){
    
    
	student* node = firstStudent;
	int n = 0;
	int Report = m; 
	int time = 1;//第一次报数 
	while(node != NULL) {
    
    
		
		if(time == Report){
    
    
			//打印编号 
			a[n++] = node->id;
			//更新报数上限 
			Report = node->passwd;
			//计数器归零 
			time = 0; //当前人出队伍后不报数,下个人报数。 
			//连接前一个节点与后一个节点 
			node->preStudent->nextStudent = node->nextStudent;
			node->nextStudent->preStudent = node->preStudent; 
			free(node);
			node = node->preStudent;
			//如果只剩自己则退出 
			if(node==node->nextStudent){
    
    
				a[n++] = node->id;
				break;
			}
		}
		
		node = node->nextStudent;
		time++;
	}
}

void check(student* firstStudent,int time){
    
    
	int n = time;
	printf("向后循环\n");
	while(n--){
    
    
		printf("%d ",firstStudent->id);
		firstStudent = firstStudent->nextStudent;
	}
	putchar('\n');
	
	n = time;
	printf("向前循环\n");
	while(n--){
    
    
		printf("%d ",firstStudent->id);
		firstStudent = firstStudent->preStudent;
	}
	putchar('\n');
}

void printfId(int a[],int n){
    
    
	printf("下面是编号:\n");
	for(int i = 0;i < n;i++){
    
    
		printf("%d ",a[i]);
	}
	putchar('\n'); 
} 

int main(void){
    
    
	int m;
	printf("请输入报数上限值\n");
	scanf("%d",&m);//初始 报数上限值
	
	int n;
	printf("请输入人数!\n");
	scanf("%d",&n);
	int a[n];
	
	//创建循环链表 
	student* firstStudent = create(n);
	
	//打印验证循环链表
	student* node = firstStudent;
	check(node,n*2+2);//循环两遍+2个以验证 
	
	//输出个人的编号到数组 
	outputCirculationReportResult(a,m,firstStudent);
	
	//输出编号到屏幕
	printfId(a,n);
	 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_45311187/article/details/111241735