Table des matières
D'abord, qu'est-ce qu'une bague Joseph ?
Implémentation de l'anneau Joseph
1. Créer des variables de structure
2. Initialisez la liste chaînée
3. Construire une liste chaînée circulaire
5. Explication complète du code et des commentaires
D'abord, qu'est-ce qu'une bague Joseph ?
L'anneau de Joseph est un problème classique dans les listes chaînées circulaires ; description du titre : n personnes forment un cercle, commencent à compter à partir de la première personne, les personnes qui comptent jusqu'à m sortent de la file d'attente, puis la personne suivante recommence à compter à partir de 1 .
Supposons que 10 personnes forment un cercle, numéroté de 1 à 10, et que le nombre est indiqué par ordre croissant. La personne qui indique 3 est éliminée. Le diagramme de processus est le suivant
Implémentation de l'anneau Joseph
Personnellement, je préfère les listes chaînées circulaires ;
1. Créer des variables de structure
typedef struct Node{
int data; //数据域
struct Node* next; //指针域
}Node;
2. Initialisez la liste chaînée
Node* Create(){
Node* head;
head = (Node*)malloc(sizeof(Node));
if (head == NULL) {
exit(1);
}
head->next = NULL;
return head;
}
3. Construire une liste chaînée circulaire
Créez un nœud temporaire tail , attribuez le nœud principal head à tail , insérez un nouveau nœud p , laissez le prochain de tail pointer vers p , et le suivant de p pointe vers le nœud suivant de head , qui est le nœud p ; en même temps le temps, laissez la queue se déplacer vers la position p
bloc de code
Node* Push(Node* head,Node* tail,int 1){
p->data=i;
tail->next =p;
p->next = head->next;
tail = p;
return head;
}
La chose la plus importante est de déplacer la queue vers la nouvelle position du nœud à chaque fois que vous insérez un nouveau nœud !
4. Supprimer la liste chaînée
void Print(Node* head){
Node* q=head;
q->next = p->next;
printf("%d ", p->data);
free(p);
p = q->next;
}
5. Explication complète du code et des commentaires
#include<stdio.h>
#include<stdlib.h>
typedef struct Node{
int data;
struct Node* next;
}Node;
//创建结构体变量
Node* Create(){
Node* head;
head = (Node*)malloc(sizeof(Node));
if (head == NULL) {
exit(1);
}
head->next = NULL;
return head;
}
int main()
{
int n, m,i;
Node * tail, * p, * q;
Node* head=Create();
scanf("%d %d", &n, &m); //输入n个人围一圈及报数m的人出局
//判断如果插入的数据为0或者以报数0为出局,则结束操作
if (n == 0 || m == 0) {
return 0;
}
else {
tail = head; //开始没有数据,故尾结点tail与头结点重合
for ( i = 0; i < n; i++) {
p = (Node*)malloc(sizeof(Node)); //插入新结点需,先申请动态内存
if (p == NULL) { //判断动态内存是否申请成功
printf("申请失败!");
exit(1);
}
p->data = i+1; //以下4步为插入新结点及数据的操作,具体分析请看上面构建循环链表
tail->next =p;
p->next = head->next;
tail = p;
}
}
p =head->next; //插入完数据后,将最后一个结点的临时结点移到第一个数据处
q =tail; //然后临时结点到尾结点处
i = 1;
while (p != q) { //首尾结点是否重合,重合则表示只剩一个数据,结束循环
if (i == m) { //对报数m的人进行出局操作
q->next = p->next; //以下四步为删除操作
printf("%d ", p->data);
free(p); //一定记得将删除链表处的内存释放,以免内存内存泄漏
p = q->next;
i = 1; //删除后,重新从1开始报数
}
else { //没有报数到m,则p,q结点都往后移一位
q = p; //先q移到p的位置
p = q->next; //然后p移到q的下一个位置
i++;
}
}
printf("%d", p->data); //打印最后一位出局的人的号数
return 0;
}