Good stuff that "gathers dust" in favorites - "Favorites never stop, action never begins"

Direction 1: Share a good question you have collected

When Xiao Yalan first learned the data structure and algorithm, it was really difficult to learn. I felt that the linked list was really difficult. After learning the following knowledge, I found that the linked list gradually became simpler. If it is now, Xiao Yalan still thinks that the knowledge points of the linked list and the OJ questions are very meaningful.

This is a blog written by Xiao Yalan related to the knowledge points of the linked list: Singly linked list - "Data Structure and Algorithm"

Double Linked List - "Data Structure and Algorithm"

Sequence table (updated version) - "Data Structure and Algorithm"

 


struct ListNode* reverseList(struct ListNode* head){
    if(head==NULL)
    {
        return NULL;
    }
    struct ListNode*n1=NULL;
    struct ListNode*n2=head;
    struct ListNode*n3=n2->next;
    while(n2!=NULL)
    {
        n2->next=n1;
        //迭代
        n1=n2;
        n2=n3;
        if(n3!=NULL)
        {
             n3=n3->next;
        }
    }
    return n1;
  
}

 

 

 

 

 

 

 

 

 

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    if (headA == NULL || headB == NULL) {
        return NULL;
    }
    struct ListNode *pA = headA, *pB = headB;
    while (pA != pB) {
        pA = pA == NULL ? headB : pA->next;
        pB = pB == NULL ? headA : pB->next;
    }
    return pA;
}

 

 

 

 

The main idea used in this topic is the idea of ​​fast and slow pointers! ! !

 

bool hasCycle(struct ListNode* head) {
    if (head == NULL || head->next == NULL) {
        return false;
    }
    struct ListNode* slow = head;
    struct ListNode* fast = head->next;
    while (slow != fast) {
        if (fast == NULL || fast->next == NULL) {
            return false;
        }
        slow = slow->next;
        fast = fast->next->next;
    }
    return true;
}

Direction 2: Share a handy technique that you have collected

A linked list is a non-sequential and non-sequential storage structure on a physical storage unit, and the logical order of data elements is realized through the link order of pointers in the linked list. The linked list is composed of a series of nodes (each element in the linked list is called a node), and the nodes can be dynamically generated at runtime. Each node consists of two parts: one is a data field that stores data elements, and the other is a pointer field that stores the address of the next node. Compared with the linear list sequential structure, the operation is more complicated. Since it does not have to be stored in order, the linked list can reach the complexity of O(1) when inserting, which is much faster than another linear list sequence table, but it takes O(n) to find a node or access a specific numbered node time, and the corresponding time complexities of linear table and sequential table are O(logn) and O(1) respectively.
Using the linked list structure can overcome the shortcoming that the array linked list needs to know the data size in advance, and the linked list structure can make full use of the computer memory space and realize flexible memory dynamic management. However, the linked list loses the advantages of random read of the array, and at the same time, the linked list has a relatively large space overhead due to the increase of the pointer field of the node. The most obvious advantage of the linked list is that the way the conventional array arranges the associated items may be different from the order of these data items in memory or on the disk, and the access of data often needs to be converted in different arrangement orders. Linked lists allow insertion and removal of nodes at arbitrary positions on the list, but do not allow random access. There are many different types of linked lists: singly linked lists, doubly linked lists, and circular linked lists. Linked lists can be implemented in many programming languages. The built-in data types of languages ​​​​such as Lisp and Scheme include the access and operation of linked lists. Procedural or object-oriented languages ​​such as C, C++ and Java rely on mutable tools to generate linked lists.

The characteristic of the linked storage representation of the linear table is to 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 and its direct successor data element, for a data element, in addition to storing its own information, it is also necessary to store an information indicating its direct successor (that is, the storage of the direct successor Location). A "node" is composed of these two parts of information, representing a data element in the linear table. One disadvantage of the chained storage representation of the linear table is that to find a number, you must start from the beginning, which is very troublesome.
According to the situation, you can also design other extensions of the linked list yourself. But generally no data will be attached to the edge, because the points and edges of the linked list are basically in one-to-one correspondence (except for the first or last node, but there will be no special cases). However, there is a special case that if the linked list supports reversing the front and back pointers in a section of the linked list, it may be more convenient to add the reverse mark to the side.
For nonlinear linked lists, you can refer to other related data structures, such as trees and graphs. In addition, there is a data structure based on multiple linear linked lists: jump list, the speed of basic operations such as insertion, deletion and search can reach O(nlogn), the same as a balanced binary tree.
The domain storing data element information is called a data domain (set the domain name as data), and the domain storing the immediate subsequent storage location is called a pointer domain (set the domain name as next). The information stored in the pointer field is also called a pointer or a link.
A linked list composed of N nodes respectively representing ,,…, is called a linked storage representation of a linear list. Since each node of this type of linked list contains only one pointer field, it is also called a single linked list. or a linear linked list. 

Structurally, linked lists can be divided into: Singly Linked, Doubly Linked List and Circular List. List), in most logarithmic cases, we will only use the following three linked lists.

Singly Linked

The storage structure of the singly linked list is relatively simple. In terms of storage, it can use a set of arbitrary storage units to store the data elements of the linear list (this set of storage units can be continuous or discontinuous). Each element contains two fields, where the field that stores data element information is called the data field; the field that stores the immediate subsequent storage location is called the pointer field. The information stored in the pointer field is called a pointer or a link. As shown in the figure below, the link points to the next node in the list, while the last node points to a null value.

 

Doubly Linked List

The storage structure of the doubly linked list is more complicated than that of the singly linked list. In the doubly linked list, there are two pointer fields in each node, one points to the direct successor and the other points to the direct predecessor. When the connection is the last connection, it points to a null value or an empty list. As shown below:

Circular linked list (Circular List)

A circular linked list is another form of linked storage structure. Its characteristic is that the pointer field of the last node in the list points to the head node, and the whole linked list forms a ring. Therefore, starting from any node in the table, other nodes in the table can be found, as shown in the following figure:

 

Similarly, a doubly linked list can also build a circular linked list. The circular linked list has two characteristics. First, there is no NULL pointer in the linked list; second, the linked list does not need to increase the storage capacity. 

  • Memory cells can be contiguous or discontiguous
  • Each node contains two parts, namely the data element field and the pointer field
  • Nodes are connected through pointer fields 

Direction 3: Dust has accumulated for so long, is this thing that was collected by you still useful to you now?

The purpose of linked list

  • Realize the file system: Linked list can be used to realize the file directory structure in the file system, each node can represent a file or a directory, and the entire file system can be regarded as a linked list structure containing multiple nodes.
  • Sorting: Linked lists can be used to implement sorting algorithms such as merge sort and quick sort. These algorithms usually require dynamic creation and deletion of nodes at runtime, which is the strength of linked lists.
  • Manage dynamic data: A linked list is a dynamic data structure that can freely add and delete nodes, so it is often used to manage dynamically sized data collections, such as file systems, operating system memory management, and network protocols.
  • Storing sparse data: Linked lists can also be used to store sparse data structures such as sparse matrices. Because linked lists can efficiently manage and store unordered collections of data, it is an efficient way to store sparse data.
  • Implement various data structures: Tables are often used to implement other efficient data structures such as queues, stacks, and hash tables. Linked lists provide efficient insertion and deletion operations that can be performed in O(1) time, while other data structures such as arrays require a large amount of data relocation.

Data structures that can be implemented with linked lists:

  1. Linear data structure: Linked lists can be used to implement linear data structures such as stacks, queues, and chained queues, and stacks and queues based on linked lists can grow dynamically, which is more flexible than array-based implementations.
  2. Hash table: The hash table can solve the problem of hash collision (Hash Collision) by using a linked list. The linked list can be used to form a hash bucket. When a hash collision occurs, the conflicting data will be added to the end of the linked list.
  3. Graphs and trees: Linked lists can be used to describe and implement complex graph and tree data structures, and each node can use a linked list to store child nodes or adjacent nodes.
  • Realize efficient memory allocator: Linked list can be used to realize the file directory structure in the file system, each node can represent a file or a directory, and the entire file system can be regarded as a linked list structure containing multiple nodes.

The linked list is mainly to facilitate the management of data with an uncertain length or quantity. Compared with the array, the linked list saves memory when processing this kind of data. Linked lists are usually not needed in dynamic languages, because the interpreter of dynamic languages ​​manages memory for you, but you can also use linked lists in dynamic languages ​​when you have special requirements for space efficiency or the efficiency of insertion actions.

Linked lists are often used to temporarily store a set of variable-length linear data in programs.

Data with such characteristics can be stored in a linked list:

1. The data is gradually increasing

2. The length of the data is indefinite. Before storing the first data, it is difficult to determine an upper limit of how much data needs to be stored in the future, or although the upper limit can be determined, the upper limit is larger than the possible length of the data in most cases. Therefore, it is not cost-effective to allocate the space according to the upper limit at one time. The linked list can apply for memory every time new data needs to be added, which will not cause waste, and will not limit the amount of data due to insufficient one application.

3. There is no need to perform random access to data according to the serial number.

The list container is provided in C++ STL, which is a linked list. At the same time, STL also provides a vector container, which can also be used to process data with the above characteristics, and vector also supports random access (that is, the above 3rd requirement can be ignored). However, when vector adds data, if the originally allocated continuous memory has been used up, it needs to reallocate the memory and copy the original data. At this time, the time complexity of inserting data is not O(1) (not constant time is up). Therefore, in addition to the above characteristics, the data that the linked list is suitable for processing has the following characteristics of the fourth point, then the linked list is the best choice:

4. It is hoped that the time complexity of each action of adding data and deleting data is O(1) (constant time).


Alright, this is the end of Xiao Yalan's sharing today, let's continue to work hard! ! !

 

 

Guess you like

Origin blog.csdn.net/weixin_74957752/article/details/132263682