I don't even know these. I dare not say I can link lists

The most detailed and easy to understand linked list in the whole network

As soon as I was a sophomore, the school stuffed me with a data structure. c linguistics is still confused. People are directly stupid when they come into contact with data structures. The teacher is full of conceptual theory. It's true. Teachers who teach data structures will default that students learn c well. First, this and that. After that, they will ask you to understand a linked list code and then imitate. They won't say where the core of a data structure is, how a data structure is formed, and where the logical thinking of writing a data structure is, How to start to complete a data structure code.

The interesting way of linked list

What is a linked list. The book says: use a group of arbitrary storage units to store the data elements of the linear table (this group of storage units can be continuous or discontinuous). Therefore, in order to represent the logical relationship between each data element ai and its direct subsequent data element ai+1, for the data element ai, in addition to storing its own information, it is also necessary to store an information indicating its direct subsequent (i.e. the location of direct subsequent storage). These two parts of information form the storage image of data element ai, which is called node. It includes two domains: the domain in which data element information is stored is called data domain; The field that stores the direct subsequent storage location is called the pointer field. The information stored in the pointer field is called a pointer or chain. n nodes are linked into a linked list.

Seems to understand, but it's still a little vague. To understand is to know that there are several nodes, and then connect them. My teacher said the same thing. He also drew a picture on the blackboard and made an example of a train carriage. I really understand. It's just a few pieces connected. It seems that I know a little about how to connect several nodes, but I don't know. I know it is connected with a pointer. My teacher also told me to point to another node with a pointer. I really understand. It's not like I'm holding a stick to point to you. finished. This is the linked list. The core of the linked list is finished. We all understand the truth. We can read and listen, but how can the code represent the linked list?

In fact, the essence of linked list is not connection at all, but the management of some or some data in memory.

When I started learning c, my teacher told me to define a variable with some data type (such as int). The meaning of data type is to apply for memory, such as an int 32-bit, a long long 64 bit, etc. It's easy to recite. Isn't that the memory size? If there is a variable, we can store the data in this variable. Note that this is a variable. What can a variable do? Can a variable only store one and one kind of data, but what if I want to store multiple data? What should I do? At this time, many people can think of arrays. OK. I define an array in the main function. How big is it? In the main function, define whether the memory requested by the variable is in the stack or in the heap? Is the definition in the function in the stack? What is the maximum memory in that stack? In fact, I don't know, but there is a standard stack called the system stack. The maximum memory of the system stack is 8MB, that is, 2 million integer data. If it is greater than 2 million, the stack will explode. However, if I want to define 10 million, there will not be 10 million memory in the stack, but it can be in the heap. Under the guarantee of memory, you can constantly apply for memory in the heap. An array is constantly applied for memory. What is this? Isn't this a sequential table? If you say that an array is a sequential table, I still have room to reject it. Why, if the size of an array is determined as soon as you are born, just as you are specified to be only one meter high, what is your feeling? This obviously loses the meaning of data storage. What is the meaning of data storage? For example, in an English dictionary, I want to save all the word explanations of the dictionary into the computer memory. Do I save one word instead of explaining how many can only be saved.

Note that I'm not talking about the sequence table. The above involves the sequential list, only because there is only one difference between the sequential list and the linked list, that is, the memory applied for by the sequential list is continuous. What is continuous. The difference between continuity and discontinuity is like a field in my family. This one belongs to my family, which is continuous; Discontinuity is like my family has a field in the south of the city and a field in the north of the city. On earth, my family also has a field here and there. Continuous is easy to say. Continuous only needs to know how big this field is and where it belongs to my family from the beginning. But what about discontinuities? If I stand on the field in the south of my city, how can I know that I still have a field in the north of the city? Then I have to insert a sign in the field in the south of the city. This sign says where the field in the north of my city is, that is, the address of the north of my city. In this way, when I stand on the field in the south of the city, I can follow the address to the field in the north of the city, Then the address of the next field is also written on the field in the north of the city. I can run to the next field along the address. When I run to a field without an address, it means that this field is the last field of my family. OK, to sum up, I started running along the address from the field in the south of the city. Can I run down as long as I know where the field in the south of the city is? But how can I know where the field in the south of the city is? I just don't know. When I came here, I asked the National Bureau of land resources for an explanation to show that the land in the south of the city belongs to my family, So as long as the description of the south of the city is OK.

I wrote a lot of words. I don't know what I wrote? If you watch it, you can watch it and play it. Then you can directly operate the code.

The simplest way to form a linked list

Oh, it's code operation. Open the editor, write the stdio header file, and write the main function. What should I do next and what should I do. Oh, I want to write a linked list. What does the linked list come from? I forgot.

Here, remember the following steps to create a linked list: node definition - > node initialization - > node release - > define head node - > tail interpolation to add nodes (with head interpolation and middle interpolation)

Node definition: why define a node? I just want to ask, what is a node? If there is no data structure, is there a node in c language? The node is not just a field mentioned above, but also a piece of memory, but there is a brand on the field. Does the brand write the address? What data type is used in c to define the variable storage address, which is not the pointer type? So the node is a field plus a brand? There is no node in c language, but there is a way in c to construct something that does not exist, that is, a structure. Therefore, the first step involves the structure in c language (knowledge points: the structure structure structure and pointer type store the address and data type to specify the size of a piece of memory).

struct Node{
    int data;//Field size, memory size
    struct Node* next;//next is a brand. It stores the address. Why use struct Node *. struct Node is the name of the data type node. Because the space size of the stored address is also the size of the node, it should be defined by the node;
};
    
//In order to change the name of the structure, the code will use the name Node in the future
typedef struct Node{
    int data;
    struct Node* next;
} Node;

Node initialization: defining a node is just a definition, just like unilaterally adding a node data type to eight basic data types. When this data type is used to define a variable, it is generally defined in a function, that is, a variable is defined in a stack. As mentioned above, the capacity in the stack is limited, so it is necessary to apply for memory in the heap. Remember that each node must be initialized.

Node *n = (Node *) malloc(sizeof(Node));//Malloc function has the function of applying for memory from the heap. Its parameter is the size of the applied memory. If it succeeds, it will return a typeless pointer to the allocated address. This pointer stores this segment of memory. It can be understood as follows: first, Node *n is the variable n that defines the data type of a Node node. This variable stores the address. malloc(sizeof(Node)) returns this pointer. Because it is a typeless pointer, it can only be used after (Node *) malloc(sizeof(Node)) strong type conversion. (malloc function requires header file stdlib.h)
int val = 1;
n->data = val;//Assign val to the node and store the real data
n->next = NULL;//To leave the sign on the field blank means that this is the last field

Node release: because the above memory is applied for, it must be released when not in use. This is a Jianghu rule. If it is not affected by the rule, the program will be indirectly affected

free(n);

**Define the head node: * * this step is what the land and Resources Bureau said above. It needs a description to indicate that the land in the south of the city belongs to my family. After defining the head node, it is a linked list with nodes. If you want to define an empty linked list, you can directly Node *head = NULL; Can

Node *head = (Node *) malloc(sizeof(Node));
head->data = 1;
head->next = NULL;

Complete code of linked list:

#include<stdio.h>
#include<stdlib.h>
typedef struct Node{
    int data;
    struct Node *next;
} Node;

int main() {
    Node *head = (Node *) malloc(sizeof(Node));
    head->data = 1;
    head->next = NULL;
    return 0;
}

Add nodes by tail interpolation:

#include<stdio.h>
#include<stdlib.h>
typedef struct Node{
    int data;
    struct Node *next;
} Node;

int main() {
    Node *head = (Node *) malloc(sizeof(Node));
    head->data = 1;
    head->next = NULL;
    
	//Create the first new node
    int val = 2;
	Node *t = (Node*) malloc(sizeof(Node));
    t->data = val;
    t->next = NULL;
    //Insert the new node at the end of the linked list
    head->next = t;
    
    //Create a second new node
    val = 3;
	Node *t = (Node*) malloc(sizeof(Node));
    t->data = val;
    t->next = NULL;
    //Insert the new node at the end of the linked list
    head->next->next = t;
    
    
    //Create a third new node
    val = 4;
	Node *t = (Node*) malloc(sizeof(Node));
    t->data = val;
    t->next = NULL;
    //Insert the new node at the end of the linked list
    head->next->next->next = t;
    return 0;
}

Add nodes by head interpolation:

#include<stdio.h>
#include<stdlib.h>
typedef struct Node{
    int data;
    struct Node *next;
} Node;

int main() {
    Node *head = (Node *) malloc(sizeof(Node));
    head->data = 1;
    head->next = NULL;
    
	//Create the first new node
    int val = 2;
	Node *t = (Node*) malloc(sizeof(Node));
    t->data = val;
    t->next = NULL;
    //Insert the new node at the end of the linked list
    t->next = head;
    t = head;//Set the new node as the header node
    
    //Create a second new node
    int val = 3;
	Node *t = (Node*) malloc(sizeof(Node));
    t->data = val;
    t->next = NULL;
    //Insert the new node at the end of the linked list
    t->next = head;
    t = head;//Set the new node as the header node
    
    
    //Create a third new node
    int val = 2;
	Node *t = (Node*) malloc(sizeof(Node));
    t->data = val;
    t->next = NULL;
    //Insert the new node at the end of the linked list
    t->next = head;
    t = head;//Set the new node as the header node
}

Insert node at a certain location: the code of header insertion and tail insertion can be referenced here, just to get a multi node linked list

#include<stdio.h>
#include<stdlib.h>
typedef struct Node{
    int data;
    struct Node *next;
} Node;

int main() {
    Node *head = (Node *) malloc(sizeof(Node));
    head->data = 1;
    head->next = NULL;
    
	//Create the first new node
    int val = 2;
	Node *t = (Node*) malloc(sizeof(Node));
    t->data = val;
    t->next = NULL;
    //Insert the new node at the end of the linked list
    t->next = head;
    t = head;//Set the new node as the header node
    
    //Create a second new node
    int val = 3;
	Node *t = (Node*) malloc(sizeof(Node));
    t->data = val;
    t->next = NULL;
    //Insert the new node at the end of the linked list
    t->next = head;
    t = head;//Set the new node as the header node
    
    
    //Create a third new node
    int val = 4;
	Node *t = (Node*) malloc(sizeof(Node));
    t->data = val;
    t->next = NULL;
    //Insert the new node at the end of the linked list
    t->next = head;
    t = head;//Set the new node as the header node
    
    
    //Create a new node
    int val = 6;
	Node *t = (Node*) malloc(sizeof(Node));
    t->data = val;
    t->next = NULL;
    
    int idx = 2;//Insertion position
    //Run to the previous node where you want to insert
    Node *p = head;//Run with a pointer
    idx--;
    while (idx--) {
		p = p->next;
    }
    //Then insert
    t-next = p->next;
    p->next = n;
}

The above has completed the formation of a linked list, and the following will be the enhanced version, that is, through function packaging and adding management nodes.

#include<stdio.h>
#include<stdlib.h>
#include<time.h>


typedef struct Node {
    int val;
    struct Node *next;
} Node;

typedef struct List {
    Node *head;
    int len;
} List;

//Initialization node
Node *initNode(int data) {
    Node *n = (Node *) malloc(sizeof(Node));
    n->val = data;
    n->next = NULL;
    return n;
}
//Release node
void freeNode(Node *n) {
    if (!n) return ;
    free(n);
    return ;
}

//Initialize linked list
List *initList() {
    List *l = (List *) malloc(sizeof(List));
    l->head = initNode(1);
    l->len = 0;
    return l;
}

//Release node
void freelist(List *l) {
    if (!l) return ;
    Node *p = l->head;
    while (p) {
        Node *k = p;
        p = p->next;
        free(k);
    }
    free(l);
    return ;
}

//insert
int insertNode(List *l, int idx, Node *n) {
    if (!l) return 0;
    if (idx < 0 || idx > l->len + 1) return 0;
    Node *p = (l->head);
    while (idx--) {
        p = p->next;
    }

    n->next = p->next;
    p->next = n;
    l->len++;
    return 1;
}
int insertList(List *l, int idx, int val) {
    Node *n = initNode(val);
    if (insertNode(l, idx, n) == 0) {
        freeNode(n);
        return 0;
    }
    return 1;
}

int main() {
    srand(time(0));
    List *l = initList();
    int cnt = 10;
    while (cnt--) {
        int val = rand() % 100;
        int i = insertList(l, 0, val);

    }
    
    Node *p = l->head;
    while (p) {
        printf("%d : %p\n", p->val, p);
        p = p->next;
    }
    return 0;
}

For deleting nodes, reversing linked lists, circular linked lists, two-way linked lists, ring linked lists and other algorithm operations, we will not explain them in detail here. As long as we understand the essence of linked lists, other algorithms are actually conceptual and theoretical problems

summary

Linked list: multiple memory blocks - > one memory block manages the next memory block

Tags: C Algorithm data structure linked list

Posted on Thu, 30 Sep 2021 19:20:32 -0400 by zachatk1