Data structure single linked list

1, Concept of linked list

1. What is a linked list

Linked list, alias linked storage structure or single linked list, is used to store data with logical relationship of "one-to-one". Unlike the sequential list, the linked list does not limit the physical storage state of data. In other words, the physical storage location of data elements stored in the linked list is random.
For example, if {1,2,3} is stored in a linked list, the physical storage state of the data is shown in Figure 1:

We can see that figure 1 can not reflect the logical relationship between the data at all. The solution of the linked list is that each data element is equipped with a pointer when stored to point to its own direct successor element. As shown in Figure 2:

As shown in Figure 2, the storage structure in which data elements are stored randomly and the logical relationship between data is represented by pointers is a chain storage structure.

2. Node of linked list

The storage of each data in the linked list consists of the following two parts:

  1. The area of the data element itself is called the data field;
  2. The area where the pointer to the direct successor element is located is called the pointer field;

    The linked list actually stores nodes one by one, and the real data elements are contained in these nodes

    The specific implementation of each node in the linked list needs to use the structure in C language. The specific implementation code is:
typedef struct Link
{
    int data;//Data domain
    struct Link *next; //Pointer field that points to a direct successor element
}link_def;//link_def is the node name, and each node is a link_def structure

Note: since the pointer in the pointer field also points to a node, it should be declared as link_def type (to be written in the form of struct Link *).

3. What are header node, header pointer and first element node

  1. Head pointer: an ordinary pointer, which is characterized by always pointing to the position of the first node of the linked list. Obviously, the header pointer is used to indicate the location of the linked list, which is convenient for later finding the linked list and making
    Use the data in the table;
  2. Node: nodes in the linked list are subdivided into header nodes, first element nodes and other nodes:
     header node: in fact, it is an empty node without any data, which is usually used as the first node of the linked list. For the linked list, the head node is not necessary. Its function is only to facilitate the solution of some practical problems;
     first element node: due to the head node (i.e. empty node), the first node with data in the linked list is called the first element node. The first element node is only an appellation for the first data node in the linked list, which has no practical significance;
     other nodes: other nodes in the linked list;
    Therefore, a complete linked list structure for storing {1,2,3} is shown in the figure:

    Note: when there is a header node in the linked list, the header pointer points to the header node; On the contrary, if there is no head node in the linked list, the head pointer points to the first element node.
    (the following operations have no header node)

2, Creation of linked list (initialization)

1. Create header pointer and current pointer (current pointer is used for operation)
2. Create the first node (and dynamically apply for memory of a node size)
3. Initialize the primitive node first
4. Create from the second node
5. Point the next of the last node to NULL

link_def *initList(int len)
{
    //1. Create header pointer and current pointer 
    link_def *head=NULL;
    link_def *cur=NULL;
    //2. Create the first node
    head = (link_def *)malloc(sizeof(link_def));
    //3. Initialize the primitive node first
    head->data = 1;
    head->next = NULL;
    cur = head;
    //4. Create from the second node
    for(int i=2;i<=len;i++)
    {
        //Create a node
        cur->next = malloc(sizeof(link_def));
        cur = cur->next; //The cur tail pointer points to the new production node
        cur->data = i;
    }
    //5. Point the last node to NULL
    cur->next = NULL;
    printf("init %d nodes successful!\n",len);
    return head;
}

3, Insert node (forward)

  1. Point the next pointer of the new node to the node after the insertion position;
  2. Point the next pointer of the node before the insertion position to the insertion node;

**Note: * * the operation of inserting elements into the linked list must be step 1 first and then step 2; On the contrary, if step 2 is performed first, unless another pointer is added as the header of the subsequent linked list at the insertion position
Otherwise, this part of the linked list after the insertion position will be lost, and step 1 cannot be realized.

Specific code implementation steps:
1. Get header
2. Apply for a node memory
3. Find the previous node where you want to insert
4. Connect the rear node
5. Disconnect the front node and point to the new node

//Insert node before inserting
link_def *insertNode(link_def *head,int node_n) //head indicates the linked list node_n is the insertion position
{
    int i=0;
    link_def *temp,*cur;
    //1. Get header
    temp = head;
    cur  = head;
    //2. Apply for a node memory
    temp = (link_def *)malloc(sizeof(link_def));
    printf("Please insert new node data:");
    scanf("%d",&temp->data);
    //3. Find the previous node where you want to insert
    for(i=0;i<node_n-1;i++)
    {
        cur = cur->next;  
    }
    //4. Connect the rear node
    temp->next = cur->next;
    //5. Disconnect the front node and point to the new node  
    cur->next = temp; 
    return head;
}

4, Delete node

Specific code implementation steps:
1. Get header
2. Point to the previous deleted node first
3. Find the deleted node
4. The pointer of the pre deleted node points to the post node of the deleted node
5. Manually release the node to be deleted to prevent memory leakage

link_def *delectNode(link_def *head,int node_n)
{
    link_def *cur,*temp;
    //1. Get header
    cur = head;
    temp = head;
    //2. Point to the previous deleted node first
    for(int i=0;i<node_n-2;i++)
    {
        cur = cur->next;
    }
    //3. Find the deleted node
    temp = cur->next;
    //4. The pointer of the pre deleted node points to the post node of the deleted node
    cur->next = temp->next;
    //5. Manually release the node to be deleted to prevent memory leakage
    free(temp);
    printf("Delect node %d is successful!\n",node_n);
    return head;
}

5, Modify node data

1. Get header
2. Move the cur pointer to the node to be modified
3. Modify data

link_def *modifyNode(link_def *head,int node_n,int data)
{
    link_def *cur;
    //1. Get header
    cur = head;
    //2. Move the cur pointer to the node to be modified
    printf("The modified node is:%d\n",node_n);
    for(int i=0;i<node_n-1;i++)
    {
        cur = cur->next;
    } 
    //3. Modify data
    cur->data = data;
    printf("Modify node complete\n");
    return head;
}

6, View data of a node

1. Get header
2. Point to the node to view

void checkNode(link_def *head,int node_n)
{
    link_def *cur;
    //1. Get header
    cur = head;
    //2. Point to the node to view
    for(int i=0;i<node_n-1;i++)
    {
        cur = cur->next;
    }
    printf("check node %d data is %d\n",node_n,cur->data);
}

7, Display (print)

1. Re point the cur pointer to the header node
2. Execute the output statement as long as the next of the node pointed to by the cur pointer is not Null.
3. Move the current pointer back

int display(link_def *head)
{
    int i=0;
    link_def *cur;
    cur = head; //Re point the cur pointer to the header node
    //As long as the next of the node pointed to by the cur pointer is not Null, the output statement is executed.
    while(cur->next)
    {
        printf("node%d is value:%d\n",i,cur->data);
        cur = cur->next; //Move the tail pointer back
        i++;
    }
}

8, Full code display

#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
    int data;//Data domain
    struct Link *next; //Pointer field that points to a direct successor element
}link_def;//link_def is the node name, and each node is a link_def structure

link_def *initList(int len)
{
    //1. Create header pointer and current pointer (current pointer is used for operation)
    link_def *head=NULL;
    link_def *cur=NULL;
    //2. Create the first node (and dynamically apply for memory of a node size)
    head = (link_def *)malloc(sizeof(link_def));
    //3. Initialize the primitive node first
    head->data = 1;
    head->next = NULL;
    cur = head;
    //4. Create from the second node
    for(int i=2;i<=len;i++)
    {
        //Create a node
        cur->next = malloc(sizeof(link_def));
        cur = cur->next; //The cur tail pointer points to the new production node
        cur->data = i;
    }
    //5. Point the last node to NULL
    cur->next = NULL;
    printf("init %d nodes successful!\n",len);
    return head;
}

//Insert node before inserting
link_def *insertNode(link_def *head,int node_n) //head indicates the linked list node_n is the insertion position
{
    int i=0;
    link_def *temp,*cur;
    //1. Get header
    temp = head;
    cur  = head;
    //2. Apply for a node memory
    cur = (link_def *)malloc(sizeof(link_def));
    printf("Please insert new node data:");
    scanf("%d",&cur->data);
    //3. Find the previous node where you want to insert
    for(i=0;i<node_n-1;i++)
    {
        temp = temp->next;  
    }
    //4. Connect the rear node
    cur->next = temp->next;
    //5. Disconnect the front node and point to the new node  
    temp->next = cur; 
    return head;
}

//Delete node
link_def *delectNode(link_def *head,int node_n)
{
    link_def *cur,*temp;
    //1. Get header
    cur = head;
    temp = head;
    //2. Point to the previous deleted node first
    for(int i=0;i<node_n-2;i++)
    {
        cur = cur->next;
    }
    //3. Find the deleted node
    temp = cur->next;
    //4. The pointer of the pre deleted node points to the post node of the deleted node
    cur->next = temp->next;
    //5. Manually release the node to be deleted to prevent memory leakage
    free(temp);
    printf("Delect node %d is successful!\n",node_n);
    return head;
}

//Modify node data
link_def *modifyNode(link_def *head,int node_n,int data)
{
    link_def *cur;
    //1. Get header
    cur = head;
    //2. Move the cur pointer to the node to be modified
    printf("The modified node is:%d\n",node_n);
    for(int i=0;i<node_n-1;i++)
    {
        cur = cur->next;
    } 
    //3. Modify data
    cur->data = data;
    printf("Modify node complete\n");
    return head;
}

//View data of a node
void checkNode(link_def *head,int node_n)
{
    link_def *cur;
    //1. Get header
    cur = head;
    //2. Point to the node to view
    for(int i=0;i<node_n-1;i++)
    {
        cur = cur->next;
    }
    printf("check node %d data is %d\n",node_n,cur->data);
}

//display
int display(link_def *head)
{
    int i=0;
    link_def *cur;
    //1. Re point the cur pointer to the header node
    cur = head; 
    //2. Execute the output statement as long as the next of the node pointed to by the cur pointer is not Null.
    while(cur->next)
    {
        printf("node%d is value:%d\n",i,cur->data);
        //3. Move the current pointer back
        cur = cur->next; 
        i++;
    }
}

int main()
{
    link_def *head;
    head = initList(5);
    display(head);

    head = insertNode(head,3);
    display(head);
    
    head = delectNode(head,3);
    display(head);

    //Modify the data of the fourth node to 6
    head = modifyNode(head,4,6);
    display(head);

    checkNode(head,4);
    display(head);

    free(head);
    return 0;
}

Operation results

Tags: C data structure linked list

Posted on Mon, 20 Sep 2021 21:22:27 -0400 by jackthebookie