preface:
In today's class, our teacher reviewed the head insertion and tail insertion, insertion and deletion of the single chain table. These children's shoes that I don't understand pay attention to my last article( https://juejin.cn/post/7022789985589788709 )Then the teacher explained the Joseph Ring. The Joseph Ring uses a circular linked list. Today we review the algorithm of Joseph Ring, By the way, preview the two-way linked list and circular two-way linked list in advance.
Once a day to prevent decadence
Your roommate may be paddling, but he never stops learning, building plank roads openly and hiding behind the scenes
1.1 Joseph Ring
Let's first learn about Joseph's ring. Joseph's ring is a tragic story. After the Romans occupied jotapat, 39 Jews hid in a cave with Josephus and his friends. 39 Jews decided that they would rather die than be caught by the enemy, so they decided to commit suicide. 41 people lined up in a circle and counted off from the first person, Every time the third person counts, the person must commit suicide, and then count again from the next one until everyone commits suicide. We use simple data, N people form a circle, count from the first, and the m will be listed. For example, N=6, M=5, the order of listing is: 5, 4, 6, 2, 3 * *, * * 1
Let's analyze it with a diagram:
The speaker's words are: a single linked list connected from beginning to end. When it meets the requirements, output it and then delete it. It is almost the same as deleting a single linked list (only repeated several times):
Write it for everyone to see. The code is as follows:
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Node { int data; struct Node *next; }link; link * creattail(int * arc, int length) {//Here we use the tail interpolation method to create the linked list int i; link * q ; //Q is used to mark the position of the previous node, and then q is connected with the next new node link * H =(link*)malloc(sizeof(link));//Create first node H->data = arc[0]; H->next = NULL; q = H; //q remember the first node for (i = 1; i<length; i++) { link * a = (link*)malloc(sizeof(link));//Create a new node q->next = a; //The last node connects the newly established node, so that each new node is created in the last node a->data = arc[i]; //Assign a value to the newly established node a->next = NULL; //Because the newly created node is the last, its pointer field is NULL q = a; //q now mark the newly established node as the last node to facilitate the later newly established nodes to connect q } return H;//Return to the first node } link * creatcycle (int * arc, int length) {//Here we use the tail interpolation method to create the linked list int i; link * q ; //Q is used to mark the position of the previous node, and then q is connected with the next new node link * H =(link*)malloc(sizeof(link));//Create first node H->data = arc[0]; H->next = NULL; q = H; //q remember the first node for (i = 1; i<length; i++) { link * a = (link*)malloc(sizeof(link));//Create a new node q->next = a; //The last node connects the newly established node, so that each new node is created in the last node a->data = arc[i]; //Assign a value to the newly established node a->next = H; //Because the newly established node is the last, we point to the head node to form a circular linked list q = a; //q now mark the newly established node as the last node to facilitate the later newly established nodes to connect q } return H;//Return to the first node } void yuesefu(link *p,int n,int m) { int i=1; link * q; q = p; int j=1; while(j<n&&p!=NULL) { if(i==m)//Judge whether the count i is equal to M. if it is equal to m, the pointer will be listed when q is reached { i=1; j++; //Count nodes printf("%d,",p->data); q->next = p->next; //The previous node connects the current next node free(p); //Release node p=q->next; //Because i assign i to 1, i point p to the next one of q } else { i++;//Missing position count + 1 q =p; //Mark the current position because p will go to the next position soon p=p->next;//To the next node } } printf("%d",p->data);//Output last node free(p); } void display(link *p) { //The output function of the linked list traverses the linked list while (p) { printf("%d ", p->data); p = p->next; } printf("\n"); } void displaycycle(link *p,int a) { // Because it is a circular linked list, no matter which node can traverse the whole table, the number of traversals to be transmitted is a int i=0; while (i<a) { i++; printf("%d ", p->data); p = p->next; } printf("\n"); } int main() { int a[6] = { 1,2,3,4,5,6}; link * cycle = creatcycle(a, 6); //Using tail interpolation method to create circular linked list displaycycle(cycle,6); //Output it yuesefu(cycle,6,5); //Joseph Ring implementation, cycle represents the circular linked list, 6 represents the summary points, and 5 is the output of the first position free(cycle); return 0; }
Effect display:
2. Two way linked list
Bidirectional linked list, also known as double linked list, is a kind of linked list. There are two pointers in each data node, pointing to the direct successor and direct precursor respectively. Therefore, starting from any node in the two-way linked list, you can easily access its predecessor node and successor node (in human words, a node can be accessed forward or backward). Think about it in combination with the stairs or elevators in life:
Deepen everyone's image with a little story
The breeze blew across the girl's face in the window. She seemed to be looking at something. The crowd downstairs and the crowd crossing the road had a boy. She looked at her until the boy looked at her. Their eyes were communicating. The girl's face was ruddy, like just open peach blossoms, slightly red, like peach, sweet and full. The boy's eyes were like electricity, Sharp and charming, they look at each other, escape from each other and lead each other. The girl quickly goes out and comes to the stairwell. She hesitates. He will go there. He can go up and down here and there. The boy hesitates. God is not beautiful. One of them goes downstairs and the other goes upstairs. They miss each other. The boy shook his head and said: "Next time you meet her, you must ask her to pay the rent," the girl sighed. "Fortunately, she ran fast, otherwise she would have to pay the rent." , hahaha, girls go downstairs to traverse the next list, boys go upstairs to traverse the port. In fact, they are equivalent to two linked lists, but some students asked. If I were the boy, I would go up half and find that she is not there, and then go down to the other side, I could meet her. It shows that our classmates are still very smart, which is equivalent to me going down Go through half of the calendar, and then go up to the starting point. This can be done in the two-way linked list. The two-way linked list is like going up and down by elevator. The floor is our data.
#include <stdio.h> #include <stdlib.h> #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Node { int data; struct Node *port,*next; }link; link * creat(int * arc, int length) {//Create using tail interpolation int i=0; link * q,* p,*head; head = q = p=(link*)malloc(sizeof(link));//Create first node q->data = arc[0]; q->next = NULL;//The first node is followed by NULL q->port = NULL;// The first node precursor is NULL for (i = 1; i<length; i++) { p = (link*)malloc(sizeof(link));//Create a new node p ->data =arc[i]; p ->port = q; //The new node precursor connects to the previous node q ->next = p;//The successor of the previous node connects the current node q =p; //Then point the mark q of the previous node to the new node p->next =NULL; //The pointer field of the new node points to NULL } return head; } void displayport(link *p) { //The output function of the linked list uses the precursor to traverse the linked list while (p) { printf("%d ", p->data); p = p->port; } printf("\n"); } void displaynext(link *p) { //The output function of the linked list uses subsequent traversal of the linked list printf("%d ", p->data); while (p->next) { p = p->next; printf("%d ", p->data); } printf("\n"); displayport(p);//Pass the last node and use the subsequent output } int main(int argc, char *argv[]) { int a[6] = { 1,2,3,4,5,6}; link * list = creat(a, 6); displaynext(list);//Use subsequent output }
The blogger uses the tail interpolation method to show the new effect:
3. Insertion and deletion of two-way linked list:
3.1 for the insertion of two-way linked list, two nodes are required. Note: to keep the successor of p, it is OK to disconnect at last, that is, the position of step 4 and other steps is not required.
void insert(link *p,int n,int m)//Insert the data m at the position after the nth { int i= 1; while(i<n) { p =p->next; i++; } link * q=(link*)malloc(sizeof(link));//Create node q->data = m;//Give the data of m to q p->next->port = q;//2. P - > new node connected to the precursor of next q->next = p->next;//1. The newly inserted node is connected p - > next q->port = p;//3. The precursor of the newly inserted node points to p p->next = q;//The successor of 4 p points to q; note: the first three positions can be moved freely }
Effect display:
3.2 the deletion of two-way linked list only needs one node
The code is as follows:
void deletelist(link *p,int n) { int i=1; while(i<n) { p =p->next; i++; } p->port->next = p->next;//First step p->next->port = p->port;//Step 2 free(p);//Step 3 }
Effect display: I deleted the data at position 3 of the linked list
3. Circular bidirectional linked list
3.1 the circular two-way linked list is similar to the circular single linked list, that is, there are multiple precursor nodes, which can be executed forward.
3.2 create a circular two-way linked list. Let's roll it up, irons
Implement the following with code:
link * creatcycle(int * arc, int length) {//Create using tail interpolation int i=0; link * q,* p,*head; head = q = p=(link*)malloc(sizeof(link));//Step 1: create the first node p->data = arc[0]; p->next = p;//The first node is followed by NULL p->port = p;// The first node precursor is NULL for (i = 1; i<length; i++) { p = (link*)malloc(sizeof(link));//Step 2: create a new node p ->data =arc[i]; p ->port = q; //Step 3: connect the new node precursor to the previous node q ->next = p;//Step 4 the successor of the previous node connects the current node p->next =head;//Step 5: the last node points to head head->port = p;//The precursor of head points to p q =p; //Then point the mark q of the previous node to the new node } return head; } void displaycycle(link *p) { //The output function of the linked list uses subsequent traversal of the linked list link * head=p; printf("%d ", p->data); p = p->next; while (p!=head) { printf("%d ", p->data); p = p->next; } printf("\n"); }
Effect display:
Before using our two-way linked list, the subsequent output should be an endless loop
Before using our bidirectional linked list, the output of the precursor should be an endless loop
Summary:
We basically operate the data structure, linear list and linked list. The insertion and deletion of circular two-way linked list are the same as the insertion and deletion of two-way list. We haven't done more operations. If you have any questions, you can comment and ask me. We can discuss it together. We still have to knock it out. The code provided by the blogger can directly build the project, You can also follow the steps summarized by the blogger, step by step. Well, it's not easy to create. I hope you like it, like it, pay attention to it, comment on it and collect it. The blogger will update it below with the data structure. If you like it, you can collect it. Put a picture and roll it up.