Overview
Two-way linked listAlso calledDouble-linked tableIs a type of linked list. Each of its data nodes has two pointers pointing to the direct next and the direct Prev. Therefore, starting from any node in the two-way linked list, you can easily access its precursor node and successor node. To identify the head and end of the linked list, set the prev pointer of the first element and the next pointer of the last element to null.
To traverse the entire two-way linked list in reverse direction and use the prev pointer to access each element in sequence from the end to the header, a pointer is added for each element, in exchange for more flexible access to the two-way linked list.
URL: http://www.cnblogs.com/archimedes/p/c-datastruct-dlinklist.html.
Bidirectional linked list Interface Definition
1. dlist_init
void dlist_init(DList *list, void (*destroy)(void *data));
Description: initializes the two-way linked list specified by list. This operation should be performed before other operations. When you call dlist_destory, the input parameters provide a method to release the dynamic space allocation.
Complexity: O (N)
2. dlist_destroy
void dlist_destroy(DList *list);
Description: destroys the two-way linked list specified by list. Other operations cannot be performed after this operation. Unless you call dlist_init again
Complexity: O (N)
3. dlist_ins_next
int dlist_ins_next(DList *list, DListElmt *element, const void *data);
Description: inserts an element into the element of the list-specified double-link table. When the linked list is empty, the element is null. The new element contains a pointer to Data, if the insert operation is successful, 1 is returned. Otherwise,-1 is returned.
Complexity: O (1)
4. dlist_ins_prev
int dlist_ins_prev(DList *list, DListElmt *element, const void *data);
Description: inserts an element into the front of the element in the list-specified double-link table. When the linked list is empty, the element is null. The new element contains a pointer to Data, if the insert operation is successful, 0 is returned. Otherwise,-1 is returned.
Complexity: O (1)
5. dlist_remove
int dlist_remove(DList *list, DListElmt *element, void **data);
Description: This operation removes the element from the list-specified double-link table. If the operation is successful, 0 is returned. Otherwise,-1 is returned.
Complexity: O (1)
6. dlist_size
int dlist_size(const DList *list);
Description: This is a macro used to calculate the number of elements in a double-link table.
Complexity: O (1)
7. dlist_head
DListElmt *dlist_head(const DList *list);
Description: This is a macro used to return the header node of the double-stranded table specified by list.
Complexity: O (1)
8. dlist_tail
DListElmt dlist_tail(const DList *list);
Description: This is a macro used to return the End Node of the double-stranded table specified by list.
Complexity: O (1)
9. dlist_is_head
int dlist_is_head(const DListElmt *element);
Description: This is a macro used to determine whether the element specified by the element is a header node. If 1 is returned, 0 is returned.
Complexity: O (1)
10. dlist_is_tail
int dlist_is_tail(const DListElmt *element);
Description: This is a macro used to determine whether the element specified by the element is the end node. If it is 0, otherwise-1 is returned.
Complexity: O (1)
11. dlist_data
void *dlist_data(const DListElmt *element);
Description: This is a macro used to return the data fields of the elements specified by the element.
Complexity: O (1)
12. dlist_next
DListElemt *dlist_next(const DListElmt *element);
Description: This is a macro used to return the successor node of the element specified by the element. If 0 is returned,-1 is returned.
Complexity: O (1)
13. dlist_prev
DListElemt *dlist_prev(const DListElmt *element);
Description: This is a macro used to return the precursor node of the element specified by the element. If 0 is returned,-1 is returned.
Complexity: O (1)
Implementation and Analysis of Two-way linked list
ABSTRACT Data Type header file (list. h ):
Typedef struct dlistelmt _ {// create the structure void * data for the double-stranded table node; // point to the data field struct dlistelmt _ * Prev of the node; // point to the node's precursor node struct dlistelmt _ * Next; // point to the node's precursor node} dlistelmt; typedef struct Dlist _ {// create a double-stranded table structure int size; // number of elements int (* match) (const void * key1, const void * key2); matched function void (* destroy) (void * data ); destructor dlistelmt * head; // point to the header node dlistelmt * tail; // point to the End Node} Dlist; // public interface void dlist_init (Dlist * List, void (* destroy) (void * Data); void dlist_destroy (Dlist * List); int dlist_ins_next (Dlist * List, dlistelmt * element, const void * data); int dlist_ins_prev (Dlist * List, dlistelmt * element, const void * data); int dlist_remove (Dlist * List, dlistelmt * element, void ** data); # define dlist_size (list) -> size) # define dlist_head (list)-> head) # define dlist_tail (list)-> tail) # define dlist_is_head (element) (elemen T)-> Prev = NULL? 1: 0) # define dlist_is_tail (element)-> next = NULL? 1: 0) # define dlist_data (element)-> data) # define dlist_next (element)-> next) # define dlist_prev (element) (element)-> PREV) # endif
Initialize a two-way linked list:
Void dlist_init (Dlist * List, void (* destroy) (void * Data) {// initialize list-> size = 0; List-> destroy = destroy; list-> head = NULL; List-> tail = NULL; return ;}
ReclaimBidirectionalLinked List:
Void dlist_destroy (Dlist * List) {void * data; // remove each element while (dlist_size (list)> 0) {If (dlist_remove (list, dlist_tail (list ), (void **) & Data) = 0 & list-> destroy! = NULL) {// call a user-defined function to release the dynamically allocated memory list-> destroy (data) ;}// no operation is performed now, release struct as prevention measure memset (list, 0, sizeof (Dlist); return ;}
Insert a new node as the direct successor node of the specified node:
Refer to the following:
// Insert the successor int dlist_ins_next (Dlist * List, dlistelmt * element, const void * Data) {dlistelmt * new_element; // element is not allowed to be null, unless list is empty. if (element = NULL & dlist_size (list )! = 0) Return-1; // allocate space for the element if (new_element = (dlistelmt *) malloc (sizeof (dlistelmt) = NULL) Return-1; // Insert the element new_element-> DATA = (void *) data into the linked list; If (dlist_size (list) = 0) {// when the linked list is null, insert to the header node list-> head = new_element; List-> head-> Prev = NULL; List-> head-> next = NULL; List-> tail = new_element ;} else {// new_element-> next = element-> next; new_element-> Prev = element; If (element-> next = NULL) when the linked list is not empty) list-> tail = new_element; else element-> next-> Prev = new_element; element-> next = new_element;} // adjust the length of the list-> size ++; return 0 ;}
Insert a new node as the direct precursor to the specified node:
// Insert the pre-defined int dlist_ins_prev (Dlist * List, dlistelmt * element, const void * Data) {dlistelmt * new_element; if (element = NULL & dlist_size (list )! = 0) // element is not allowed to be null unless list is empty. return-1; if (new_element = (dlistelmt *) malloc (sizeof (dlistelmt) = NULL) // allocate space for element return-1; // Insert the element new_element-> DATA = (void *) data into the linked list; If (dlist_size (list) = 0) {// when the linked list is null, insert to the header node list-> head = new_element; List-> head-> Prev = NULL; List-> head-> next = NULL; List-> tail = new_element ;} else {// when the linked list is not empty, insert new_element-> next = element; new_element-> Prev = element-> Prev; If (element-> Prev = NULL) list-> head = new_element; else element-> Prev-> next = new_element; element-> Prev = new_element;} // adjust the length of the list-> size ++; return 0 ;}
Delete a specified node:
// Delete the specified node int dlist_remove (Dlist * List, dlistelmt * element, void ** data) {// It is not allowed to delete the null element or delete the element if (element = NULL | dlist_size (list) = 0) Return-1; // Delete the element * Data = element-> data from the table; If (element = List-> head) {// Delete the header node list-> head = element-> next; if (list-> head = NULL) // If the element is the end node list-> tail = NULL; else element-> next-> Prev = NULL ;} else {// Delete the node element in the table-> Prev-> next = element-> next; If (element-> next = NULL) list-> tail = element-> Prev; else element-> next-> Prev = element-> Prev;} // release the allocated node free (element ); // adjust the table length list-> size --; return 0 ;}
C. Implement a Universal Data Structure-two-way linked list