(Original) insert a single-chain table in C Language
For more information, see: http://www.360doc.com/showWeb/0/0/199614715.aspx
The procedures for inserting a single-chain table in C language may not be familiar to anyone anymore. The logic involved is very simple,
But it is not that easy to write the program completely and correctly. Because it involves: 1. Judge the end of the Loop:. If a node is found to be larger than the value of the inserted node, it indicates that the position to be inserted is found, and B is located before the node with a larger value. The current linked list does not have a value greater than this node, so we need to put the node to be inserted at the end of the linked list. When the cycle ends, the condition is whether the pointer of the current traverse table is null. C. If the value of the node to be inserted is smaller than the value of all nodes (we only need to judge that the node is smaller than the first node), we need to insert the node to the head of the linked list, and modify the linked list header pointer. For A, it is the basic process of our program in most cases. For B and C, we can treat it as a special case and process it separately. In fact, if we use the "header node" method, we don't have to deal with C. At this point, the header node is just a blank node, and the link pointer in it points to the first node in the linked list where the node we actually want to use is located. Then, even in case of C, we only need to point the next pointer of the newly inserted node to the first node, that is, the node pointed by the header node, head-> next points to the newly inserted node. If Prev points to the header node before scanning, pcur points to the current scan node, pnew_node-> link = pcur; prev-> link = pnew_node; you can process A and C in a unified manner. Of course, this is not the method I want to introduce here. In pointer on C, another clever understanding is described. This understanding is based on "when moving to the next node, we save a next pointer to the next node", instead of a pointer to the previous node, that is, no Prev pointer is required. In addition to the first node, insert at other locations actually modifies the link field of the previous node. We will focus on the Link field instead of the node pointer. The example program is as follows: # If 1 # include <stdio. h> # include <stdlib. h> # define insert_ OK 0 # define insert_err-1 typedef struct node {struct node * link; int value;} node; int list_insert (node ** linkp, int node_val) {node * pcur; node * pnew_node;/* find the correct insert position by accessing the linked list in sequence, until a node whose value is greater than or equal to the new value is found */while (pcur = * linkp )! = NULL & pcur-> value <node_val) {linkp = & pcur-> link;} pnew_node = (node *) malloc (sizeof (node )); if (pnew_node = NULL) {return insert_err;} pnew_node-> value = node_val; pnew_node-> link = pcur; * linkp = pnew_node; return insert_ OK ;} void print_link_list (node * proot) {node * P = proot; printf ("data in link list are: \ n"); While (P! = NULL) {printf ("node_val = % d \ n", p-> value); P = p-> link ;}} int main () {node * phead = NULL; int i4_ret = 0; i4_ret = list_insert (& phead, 5); If (i4_ret <0) {printf ("list insert fail: node_val = 5 \ n ");} i4_ret = list_insert (& phead, 10); If (i4_ret <0) {printf (" list insert fail: node_val = 10 \ n ");} i4_ret = list_insert (& phead, 15); If (i4_ret <0) {printf (" list insert fail: node_val = 15 \ N ");} print_link_list (phead); printf (" test insert_list function with 3, 12, 20 \ n "); printf (" now try to insert 3: \ n "); i4_ret = list_insert (& phead, 3); If (i4_ret <0) {printf ("list insert fail: node_val = 3 \ n ");} printf ("now try to insert 12: \ n"); i4_ret = list_insert (& phead, 12); If (i4_ret <0) {printf ("list insert fail: node_val = 12 \ n ");} printf (" now try to insert 20: \ n "); i4_ret = List_insert (& phead, 20); If (i4_ret <0) {printf ("list insert fail: node_val = 20 \ n");} print_link_list (phead ); system ("pause"); Return 0 ;}# when the endif parameter is passed, linkp is assigned as & phead, that is, we can modify phead in the function (the address is passed ), if the insert position is before the first node, the loop for finding the insert position will exit directly. In this case, pcur = * linkp, so pnew_node should point to pcur, in addition, * linkp should point to the node to be inserted. If the inserted position is another location, linkp will point to the next node pointed to by pcur Through cyclic search. When the Insertion Location is found, pcur points to the next node of the node to be inserted, and the link members in the previous node will point to by linkp. Therefore, pnew_node-> link = pcur; and the link pointer of the previous node points to linkp, so the expressions pnew_node-> link = pcur; and * linkp = pnew_node; take into account the situation A and C. P-> the link actually points to the next node, so the pcur = pcur-> link statement can be eliminated by using pcur = * linkp, because the latter is already the node pointed to by pcur-> link. I have to mention that * The use of linkp and linkp should not be incorrect. Because if linkp points to the first node and assigns a value to * linkp, the node will be modified. Make sure that your assignment is correct. In this example, linkp is the link pointer to the node to be inserted, or the pointer to the first node. If you cannot understand this idea well, follow the most skillful and error-prone method !!