La lista enlazada circular implementa el problema de Joseph

fuente del problema

inserte la descripción de la imagen aquí

Solución y Proceso

método

La lista circular enlazada de la estructura de datos para principiantes, simplemente usando la lista circular enlazada puede resolver fácilmente los problemas anteriores.

el código

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

typedef int Elemtype;
#define len sizeof(Node)
#define N 41                      //总人数  41
#define m 3                       //密码固定为3

typedef struct Node
{
    
    
	Elemtype data;
	struct Node* next;
}Node;

typedef struct Node Linklist;

Linklist* Creat_list();
void Out_list(Linklist *L);
void ysf_out_list(Linklist *L);

void main()
{
    
    
	Linklist *L;
	L = Creat_list();
	printf("链表输出:");
	Out_list(L);
	printf("死亡序列:");
	ysf_out_list(L);
}

// <初始化函数>
Linklist* Creat_list()
{
    
    
	Linklist *h;
	Linklist *p;
	Linklist *s;
	int i = 1;

	h = (struct Node*)malloc(len);
	h->next = NULL;

	p = h;
	while(i<=N)
	{
    
    
		s = (struct Node*)malloc(len);
		s->data = i;                     //循环链表的编号域data域从1依次赋值
		s->next = NULL;
		p->next = s;
		p = s;
		i++;
	}
	p->next = h->next;
	free(h);

	return p;
}

// <初始化链表输出函数>
void Out_list(Linklist *L)
{
    
    
	Linklist *p;
	int i = 1;
	p = L->next;

	while(i<=N)
	{
    
    
		if(i<N)
		{
    
    
			printf("%d->",p->data);
			p = p->next;
		}
		if(i == N)
		{
    
    
			printf("%d",p->data);
		}
		i++;
	}
	//printf("\n%d\n",p->next->data);       //仅用于测试
	printf("\n\n");
}

// <约瑟夫环问题函数>
void ysf_out_list(Linklist *L)
{
    
    
	Linklist *temp;
	Linklist *p;
	int i = 1;
	int j = 1;
	int t;

	p = L;
	t = m%N;

	while(i<=N)
	{
    
    	
		for(j=1;j<t;j++)
		{
    
    
			p = p->next;
		}
		if(i<N)
		{
    
    
			printf("%d->",p->next->data);
		}
		if(i==N)
		{
    
    
			printf("%d",p->next->data);
		}	
		temp = p->next;
		p->next = temp->next;
		free(temp);	
		i++;
	}
	printf("\n\n");
}

ejecutar los resultados de la prueba

inserte la descripción de la imagen aquí

Preguntas avanzadas de Joseph

Revisión y enunciado del problema

inserte la descripción de la imagen aquí

la diferencia

<1> Cada nodo tiene un dominio de contraseña adicional, que se utiliza para almacenar el límite superior de sus respectivos informes.
<2> En comparación con el problema simple de Joseph, solo necesita superar el problema de que el valor de la contraseña cambiará dinámicamente y simplemente modificar el código anterior usando una lista enlazada circular.

el código

// ★★★假设共有5个节点(如果想增加更多的节点,可以在宏定义中,仅修改N的值即可)★★★
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef int Elemtype;
#define len sizeof(Node)
#define N 5                     //★★★总人数确定值,本例假设为 5 

typedef struct Node
{
    
    
	int skew;                   //密码
	Elemtype data;              //编号、数据
	struct Node* next;          //指针
}Node;

typedef struct Node Linklist;

Linklist* Creat_list();
void Out_list(Linklist *L);
void ysf_out_list(Linklist *L);

void main()
{
    
    
	
	Linklist *L;
	L = Creat_list();
	
	printf("链表输出:");
	Out_list(L);
	printf("死亡序列:");
	ysf_out_list(L);
}

Linklist* Creat_list()
{
    
    
	Linklist *h;
	Linklist *p;
	Linklist *s;
	int i = 1;
	printf("★★★进阶约瑟夫问题★★★\n\n");
	h = (struct Node*)malloc(len);
	h->next = NULL;

	p = h;
	while(i<=N)
	{
    
    
		s = (struct Node*)malloc(len);
		s->data = i;                           // 循环链表的编号域data域从1依次赋值
		printf("请输入第%d个节点的密码:",i);
		scanf("%d",&s->skew);                  // 循环链表的密码域skew
		printf("\n");
		//s->skew = N-i+1;
		s->next = NULL;
		p->next = s;
		p = s;
		i++;
	}
	p->next = h->next;
	free(h);

	return p;
}

// <初始化链表输出函数>
void Out_list(Linklist *L)
{
    
    
	Linklist *p;
	int i = 1;
	p = L->next;

	while(i<=N)
	{
    
    
		if(i<N)
		{
    
    
			printf("%d->",p->data);
			p = p->next;
		}
		if(i == N)
		{
    
    
			printf("%d",p->data);
		}
		i++;
	}
	//printf("\n%d\n",p->next->data);    仅仅用于测试,可以忽略
	printf("\n\n");
}

// <进阶约瑟夫环问题>
void ysf_out_list(Linklist *L)
{
    
    
	Linklist *temp;
	Linklist *p;
	int i = 1;
	int j = 1;
	int t;
	p = L;

	//printf("%d\n",p->next->data); //仅仅用于测试,可以忽略
	//printf("%d\n",p->next->skew);
	t = p->next->skew;              //★★★将第一个节点的skew值作为初始报数上限,并从此处开始执行循环       
	while(i<=N)
	{
    
    
		//t = m%N;                  //仅仅用于测试,可以忽略
		
		for(j=1;j<t;j++)
		{
    
    
			p = p->next;
		}
		if(i<N)
		{
    
    
			printf("%d->",p->next->data);
		}
		if(i==N)
		{
    
    
			printf("%d",p->next->data);
		}
		temp = p->next;
		t = p->next->skew;          //★★★修改t值:将出列的下一个的skew值作为t值->报数上限
		p->next = temp->next;
		free(temp);
		i++;
	}
	printf("\n\n");
}

ejecutar los resultados de la prueba

inserte la descripción de la imagen aquí

Resumir

Estructura de datos para principiantes, ¡sigue adelante! ! ! !

Supongo que te gusta

Origin blog.csdn.net/MZYYZT/article/details/113525090
Recomendado
Clasificación