Table of contents
3. Construct a circular linked list
5. Complete code and comments explanation
First what is a joseph ring
Joseph's ring is a classic problem in circular linked lists; title description: n people form a circle, start counting from the first person, people who count to m get out of the queue, and then the next person starts counting from 1 again . The person who counts to m will go out of the circle, and so on, until everyone is out of the circle;
Assume that 10 people form a circle, numbered from 1 to 10, and the number is reported in ascending order. The person who reports 3 is out. The process diagram is as follows
Joseph ring implementation
I personally prefer circular linked lists;
1. Create structure variables
typedef struct Node{
int data; //数据域
struct Node* next; //指针域
}Node;
2. Initialize the linked list
Node* Create(){
Node* head;
head = (Node*)malloc(sizeof(Node));
if (head == NULL) {
exit(1);
}
head->next = NULL;
return head;
}
3. Construct a circular linked list
Create a temporary node tail , assign the head node head to tail , insert a new node p , let the next of tail point to p , and the next of p point to the next node of head , which is node p ; at the same time, let tail move to p position to prepare for the insertion of the next node; in this way, a circular linked list is initially completed;
code block
Node* Push(Node* head,Node* tail,int 1){
p->data=i;
tail->next =p;
p->next = head->next;
tail = p;
return head;
}
The most important thing is to move the tail to the new node position every time you insert a new node!
4. Delete linked list
void Print(Node* head){
Node* q=head;
q->next = p->next;
printf("%d ", p->data);
free(p);
p = q->next;
}
5. Complete code and comments explanation
#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;
}
If there are any shortcomings, I hope you guys can give me some pointers in the comment area!