03. Linear table (2) chain storage structure. Single-chain table 1, chain-chain
Chain storage structure. Single-chain table 11. Basic ConceptsTo express the logical relationship between each data element ai and its direct successor Data Element ai + 1, for data element ai, besides storing its own information, you also need to store a direct successor information (that is, the direct successor storage location) (1) data domain: the domain that stores the data element information of a linear table is called a data domain; (2) pointer domain: the domain that stores the direct successor location (the address of the next data element) is called a pointer domain, and the information stored in the pointer domain is a pointer or chain. (3) Node ): A storage image of data element ai is composed of two parts: data domain and pointer domain. It is called a node. (4) Head pointer: The storage location of the first node in the linked list is called the head pointer. Therefore, the access to the entire linked list must start with the first pointer. (5) header node: to facilitate operations on the linked list, weBefore the first nodeA node is attached, that isHeader node.The data field of the header node can store additional information such as the length of a linear table without any information. The pointer field of the header node stores the pointer pointing to the first node.
Note 1: What are the similarities and differences between the head pointer and the head node? Head pointer: a. Head pointer refers to the storage position pointer of the linked list pointing to the first node. If the linked list has a head node, It is a pointer to the head node. B. the header pointer is used as an identifier, so it is often used to name the linked list. c. no matter whether the linked list is empty or not, the header pointer is not empty. The header pointer is a required element of the linked list. Header node:. the header node is set up for unified and convenient operations. It is placed before the node of the first element, and its data field is generally meaningless (or the length of the linked list can be stored); B. with the header node, insert and delete the first node before the first element node, and the operation is the same as that of other nodes; c. the header node is not necessarily a required element of the linked list.
2. Single-chain tableN nodes (ai storage images) chain to form a linked list, that is, linear tables (a1, a2 .... because each node of the linked list only contains one pointer field, it is called a single-chain table.
3. Sample Code of the chained storage structure pointer/* The storage structure of a single-chain table of a linear table * consists of the data domain storing data elements and the pointer domain storing the subsequent node addresses */typedef int ElemType;
Typedef struct Node {ElemType data; // int type member variable, used as the data field of the Node, struct Node * next; // struct Node type member pointer variable, used as the pointer field of the Node} Node; typedef struct Node * LinkList; // defines the LinkList annotation: (1) Node is equivalent to the struct Node struct; * LinkList is equivalent to the struct Node struct (2) if the pointer p is a pointer to the I-th element of a linear table, the ai data and pointer fields of the node are p-> data, p-> next: p-> the data value is the data field of the node ai, And the content is a data element; p-> the value of next is a pointer pointing to the (I + 1) storage address of each element (node), that is, the pointer to ai + 1, that is, p-> data = ai p-> next-> data = ai + 1
4. Read, insert, and delete a single-chain table
(1) reading a single-chain tableImplementation operation: GetElem (LinkList L, int I, ElemType * e) extracts the I data element from the single-chain table L and stores it in the address space pointed to by the pointer variable I. Algorithm idea: Unlike the sequential storage structure of a linear table, it is easy to read an element from any location. The data elements of a single-chain table must be read from the beginning, that is, the working pointer p is removed. A. declare a node p pointing to the first node of the linked list and initialize j to traverse B from 1. when j <I, the p pointer is moved backward from the traversal table to the next node. j accumulates 1 until p is null at the end of the linked list. It indicates that the element I does not exist. c. If p is a null node or the traversal position exceeds I, an exception is thrown. d. the query is successful and the data of node p is returned. Source code implementation:/* initial condition: the ordered linear table L already exists. 1 = I <= ListLength (L) * operation structure: use e to return the value of the I-th Data Element in L */# define OK 1 # define ERROR 0 typedef int Status;
Typedef int ElemType;
Typedef struct Node * LinkList; // defines the LinkList
Status GetElem (LinkList L, int I, ElemType * e) {int j; LinkList p; // declare a node p = p-> next; // Let the node p point to the first node j = 1 of the linked list L; while (p & j <I) // traverse from the first node of the linked list until j = I-1, let p point to the node where the storage I-1 location is located {p = p-> next; // Let p point to the next node j ++;} if (! P | j> I) return ERROR; * e = p-> data; // the query is successful, store the data of the I element in the linked list to the return OK space pointed to by pointer e;} Note: p is a newly defined node, while (p & j <I) the role is to make the node p from the first node of the linked list to traverse until j = I-1, let p point to the storage I-1 location of the node, if p is null at the end of the linked list, the I-th element does not exist.
(2) single-chain table insertionImplementation operation: ListInsert (LinkList * L, int I, ElemType e), insert Data Element e to the I position of a single-chain table L. algorithm idea: s-> next = p-> next; p-> next = s;. declare a node p pointing to the first node of the linked list and initialize j to traverse B from 1. when j <I, let the p pointer move backward and keep pointing to the next node. j accumulates 1 until p is null at the end of the linked list, it indicates that the I-th element does not exist. C. if p is a null node or the traversal position exceeds I, an exception d is thrown. if the search is successful,-generate an empty node in the System s-assign the data element e to s-> data; -Insert standard statement s-> next = p-> next, p-> next = s source code implementation for a single-chain table:/* initial condition: the ordered linear table L already exists, 1 = I <= ListLength (L) * operation structure: insert Data Element e to the I position of a single-chain table L */# define OK 1 # define ERROR 0 typedef int Status;
Typedef int ElemType;
Typedef struct Node * LinkList; // defines the LinkList
Status ListInsert (LinkList * L, int I, ElemType e) {int j; LinkList p, s; // declare a node p = * L; j = 1; while (p & j <I) // traverse from the first node of the linked list until j = I-1, let p point to the node where the storage I-1 location is located {p = p-> next; // Let p point to the next node j ++;} if (! P | j> I) return ERROR; s = (LinkList) malloc (sizeof (Node); // generate a new Node, that is, a small space is found in the memory, prepare to store e data s node s-> data = e; // key 1: search successful, assign the Data Element e to the data domain s-> next = p-> next; // key 2: assign the successor node of node p to the successor node of node s (p-> next is the node pointing to the next storage address of node p) p-> next = s; // key 3: set the successor node of node p to node s return OK;} Note: p is a newly defined node, while (p & j <I) the role is to make the node p from the first node of the linked list to traverse until j = I-1, let p point to the storage I-1 location of the node, if p is null at the end of the linked list, the I-th element does not exist.
(3) single-chain table DeletionImplementation operation: ListDelete (LinkList * L, int I, ElemType * e), delete the I data element in a single-chain table L, and store the data in the space pointed to by the pointer e. algorithm idea: {p-> next = p-> next (or q = p-> next; p-> next = q-> next)}. declare a node p pointing to the first node of the linked list and initialize j to traverse B from 1. when j <I, let the p pointer move backward and keep pointing to the next node. j accumulates 1 until p is null at the end of the linked list, it indicates that the I-th element does not exist. C. if p is a null node or the traversal position exceeds I, an exception d is thrown. if the search is successful, assign the node p-> next to q-set the successor node of node p to q-> next, that is, p-> next = q-> next; -store the data field data of node q to ee. release the q node and return the successful mark source code implementation:/* initial condition: the ordered linear table L already exists. 1 = I <= ListLength (L) * operation structure: delete the I-th data element in a single-chain table and store the data in the space pointed to by pointer e */# define OK 1 # define ERROR 0 typedef int Status;
Typedef int ElemType;
Typedef struct Node * LinkList; // defines the LinkList
Status ListInsert (LinkList * L, int I, ElemType * e) {int j; LinkList p, q; // declare a node p = * L; j = 1; while (p-> next & j <I) // traverse from the first node of the linked list until j = I-1, let p point to the node where the storage I-1 location is located {p = p-> next; // Let p point to the next node j ++;} if (! P | j> I) return ERROR; q = p-> next; // set q to the next node p-> next = q-> next; // set the successor node of q to the successor node of p * e = q-> data; // send the data in the q node to e free (q ); // after the setting is complete, let the system reclaim this node and release the memory return OK ;}
Sublimation NOTE 2: Analysis of s, p, s-> data, s-> next, p-> next? (1) LinkList p, s: declare two nodes p and s, including the data domain and pointer domain; (2) s-> data: the data domain of node s, the value is a data (3) s-> next: pointer field of node s, and its value is the storage address of the next node (4) s-> next = p-> next: Assign the storage address of the next node of node p to the s node pointer field (5) p-> next = s; set node s to the next node of p. In fact, (4) (5) we can understand this: assume that the initial linked list is connected to two nodes p and q, that is ...... -p-q -......, now we need to insert a node s between node p and q. The method is as follows: since p-> next = q, s-> next = q // node s is followed by q p-> next = s // node p is followed by s, in this case, ...... -p-s-q -......
5. Performance Analysis of sequential Storage Structure(1) Search: the time complexity is O (1), and the worst case event complexity is O (2) (2) Delete and insert: the insertion and deletion of a single-chain table are mainly composed of two parts: the first part is to traverse the I-th element of the query; the second part is to insert and delete elements. From the whole algorithm, we can easily export the elements: their time complexity is O (n ). If we do not know the pointer position of the I-th element, the data structure of a single-chain table is in the insert and delete operations, and the sequence storage of the linear table is dismissed, there is no big advantage. However, if we want to insert 10 elements from the position I, for the sequential storage structure, it means that each insert needs to move n-I elements, each time it is O (n ). For a single-chain table, we only need to find the pointer at position I for the first time, which is O (n). Next, we simply move the pointer by assigning values, the time complexity is O (1 ). Conclusion: The more frequently you insert or delete data, the more efficient the single-chain table is.