This is a single-chain list with a header node. Previous studies of single-chain header node data fields are not useful, where the header node data fields hold the length of the list.

The core is to use the length of the head node to cycle, find any node you want to locate, and then you can do all kinds of operations at will. Assuming the header node subscript is 0, the first element subscript is 1, and so on, the header node does not take into account, the number of elements is the subscript of the last element, which is different from the usual array. Here, the number of elements whose subscripts are several, as shown in the following figure

Let's start with the core code:

int length = p->data; //Here you save the header node data field, which is the length of the chain table for (int i = 1; i <= length; i++) { p = p-> next; }

P = p->next is the most core code. Originally, the pointer points to the current node, executing the code will point the pointer to the next node, using the above loop to find the location of the last element, the pointer points to the last element, as long as you understand this other very well. To tidy up its logic, before entering the loop, our p points to the head node, which is when the function is passed in. Then the loop starts, assuming that we have a length of 10, when i = 1, we judge 1 < 10, go into the loop and execute P = P - >next; At this point our p-pointer was originally from the first node, now it points to the first node, then i++, then i= 2, then I or < 10, goes into the loop, then p points to the second node, and so on, when i++ goes to i = length, we make a judgment, the condition is established and goes into the loop, then p points to the last node, again i++, I equals 11, the condition is not established to exit the loop, according to the logic above, we can see that with this code, we specify how much length to use, which will eventually point to the node, as follows:

void insert(int index) { for (int i = 1; i <= index; i++) { ` p = p->next; } }

A subscript value is passed in, loops through, and finally points to the node's location, which makes it easy for us to do things like print TF ("%d\n", p->data) to print the node's value. Inserting a value after this node is described below. The main idea of insertion is understood in the appended drawings.

//The parameter p passes into the chain header node, Index inserts the node after specifying the number of elements, and key is the value of the data field void insert(Node* p, int index, int key) { p->data++;//Insert an element, chain length + 1 //This is the following cycle for (int i = 1; i <= index; i++) { p = p->next; }//p has now pointed to the position of the subscript //Create this node Node* node = (Node*)malloc(sizeof(Node)); //Data Domain Assignment node->data = key; //This is the core idea of inserting nodes //The pointer field of the current node points to the next node of P node->next = p->next; //The p-pointer field points to this node p->next = node; }

If there is only a header node in the chain table, the loop judgment is not established directly. i initial value is 1, not <= 0, go directly to the code below the loop, insert the first element after the header node, and the pointer field of the start header node points to NULL, in which case node->next is equivalent to NULL, which also ensures the rule that the pointer field of the endpoint of the chain table points to null. If there is only one element in the list, p will point to this first element and then insert a new node behind it, so neither of the above two special cases should be considered as problematic.

Next, delete a node by pointing the pointer field of the previous node to the next node of the node to be deleted, as shown in the figure:

Understand this idea to understand the deletion operation

//index specifies which element to delete void delete(Node* p, int index) { //If the length of the list equals 0, no deletion is necessary if (!p->data) return; //Delete an element, chain list length minus 1 p->data--; //Save the previous node of the node to be deleted Node* pre; //pre here holds the pointer to the previous node of the node to be deleted //Because there is a logic problem when performing the free operation without saving for (int i = 1; i <= index; i++) { pre = p; p = p->next; }//End of loop, p points to the node to be deleted, pre points to a node on the node to be deleted //The core code implementation for deletion is the following two sentences //The pointer field of the previous node of the node to be deleted points to the next node of the node to be deleted pre->next = p->next; //Release node space to be deleted free(p); p = NULL; }

There is no pointer to save the previous node, only a pointer P is used. If only p points to the node to be deleted, we will not find the previous node of the node to be deleted. Or if we point P at the previous node of the node to be deleted, we will do the following

//p points to a node on the node to be deleted p->next = p->next->next; /*P->next is the next node of the node to be deleted, the node to be deleted can not be found, there is no way to free*/ free(p->next);

Through the above two operations, the main operations of the entire chain table are basically completed, the others are very simple, the complete code is attached below

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 typedef struct node { 5 int data; 6 struct node* next; 7 }Node; 8 //Initialize the operation, create a header node, the data field is 0, that is, the chain length is 0 9 Node* init() { 10 Node* head = (Node*)malloc(sizeof(Node)); 11 head->data = 0; //The pointer field is empty, and the pointer field of the last node in the list is empty 12 head->next = NULL; //Return the header node pointer 13 return head; 14 } 15 //Append operation, similar to insert operation 16 void append(Node* p, int key) { 17 int length = p->data; 18 p->data++; 19 for (int i = 1; i <= length; i++) { 20 p = p->next; 21 } 22 Node* node = (Node*)malloc(sizeof(Node)); 23 node->data = key; 24 node->next = p->next; 25 p->next = node; 26 } 27 //Insert operation, insert element Key after specified position 28 void insert(Node* p, int index, int key) { 29 p->data++; 30 for (int i = 1; i <= index; i++) { 31 p = p->next; 32 } 33 Node* node = (Node*)malloc(sizeof(Node)); 34 node->data = key; 35 node->next = p->next; 36 p->next = node; 37 } 38 //Traversal operation 39 void for_each(Node* p) { 40 int length = p->data; 41 for (int i = 1; i <= length; i++) { 42 p = p->next; 43 printf("%d ", p->data); 44 } 45 printf("\n"); 46 } 47 //Delete operation 48 void delete(Node* p, int index) { 49 if (!p->data) return; 50 p->data--; 51 Node* pre; 52 for (int i = 1; i <= index; i++) { 53 pre = p; 54 p = p->next; 55 } 56 pre->next = p->next; 57 free(p); 58 p = NULL; 59 } 60 //Sort the list by bubbles and come back after you have mastered the sort by bubbles 61 void bubble_sort(Node* p) { 62 int length = p->data; 63 Node* head = p; 64 int tmp; 65 for (int i = length; i > 1; i--) { 66 p = head; 67 for (int j = 1; j < i; j++) { 68 p = p->next; 69 if (p->data > p->next->data) { 70 tmp = p->data; 71 p->data = p->next->data; 72 p->next->data = tmp; 73 } 74 } 75 } 76 } 77 78 int main() 79 { 80 srand((int)time(NULL));//Random Number Seed 81 Node* head = init(); //Insert ten random numbers into the list of chains 82 for (int i = 0; i < 10; i++) { 83 append(head, rand() % 99); 84 } 85 for_each(head); //Insert 112 After 5th node 86 insert(head, 5, 112); 87 printf("Insert results:\n"); 88 for_each(head); //Delete the third node 89 delete(head, 3); 90 printf("Delete results:\n"); 91 for_each(head); 92 bubble_sort(head); 93 printf("Sort results(NB): \n"); 94 for_each(head); 95 96 return 0; 97 }

Run result:

The schematic diagrams inserted and deleted above all come from the author's article...

https://blog.csdn.net/Endeavor_G/article/details/80552680?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163526647416780262527074%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=163526647416780262527074&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~top_positive~default-1-80552680.pc_v2_rank_blog_default&utm_term=%E9%93%BE%E8%A1%A8&spm=1018.2226.3001.4450)