first, the analysis
In a single-linked list, with the next pointer, the time complexity of finding the next node is O (1), and if you are looking for the previous node, the worst time complexity is O (n), which you will find every time you start from scratch. In order to overcome this shortcoming introduced a doubly linked list design:
doubly linked list (doublelinked list): In each node of a single-linked list, set a pointer field to its predecessor node. The doubly linked list has two pointer fields, one pointing directly to the precursor, and the other pointing directly to the successor.
/* Doubly linked list storage structure for linear table */
typedef struct DULNODE
{
elemtype data;
struct Dulnode *prior;//Direct precursor pointer
struct Dulnode *next;//Direct successor pointer
}dulnode,*dulinklist;
The empty list of loops leading nodes of a doubly linked list is shown in the figure:
The doubly linked list of the leading nodes of a non-empty loop is shown in the following figure:
Nonsense: A node in a doubly linked list P, his successor is its own, that is, p;
P->next->prior = P =->prior->next
ii. insertion of elements
The node of element e is S, and the following actions are required to implement the node s insertion between nodes P and P->next:
S->prior =p;//P is assigned to the precursor of S, as shown in Figure ①
S->next =p->next;//assigns P->next to the successor of S, as shown in Figure ②
P->next->prior= s;//The S to P->next's precursor, as shown in the figure ③
P->next = s;//assigns S to the successor of P, as shown in Figure ④
The key is their order, as the 2nd and third steps are p->next. If the 4th step is performed first, it causes the P->next to advance to s so that the inserted work is not finished. To understand the memory, the order of insertion is to take care of the predecessor and successor of S, and then fix the precursor of the node, and finally solve the successor of the former node.
iv. deletion of elements
Delete Node P:
P->prior->next = p->next;//assigns the P->next to the successor of P->prior, as shown in the figure ①
P->prior->prior = p->prior;//assigns P->prior to P->next's precursor, as shown in ②
Free (p);
The most important feature of a doubly linked list is the time spent in exchanging space for the program to run faster.
C-language implementation of a doubly linked list:
#include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <string.h> enum {print_list
= 1, Print_list_reve, List_len, Is_null, Clear_list, Insert_eml_list, Delete_eml_list, dest_list};
Print option void Help () {printf ("\ n");
printf ("%d. Print bidirectional list \ n", print_list);
printf ("%d. Reverse print bidirectional list \ n", Print_list_reve);
printf ("%d. List length \ n", List_len);
printf ("%d. Determine if the list is empty \ n", is_null);
printf ("%d. empty linked list \ n", clear_list);
printf ("%d. Insert element \ n", insert_eml_list);
printf ("%d. Delete element \ n", delete_eml_list);
printf ("%d. Release list \ n", dest_list);
printf ("0. exit \ n");
printf ("\ n"); } typedef struct DULNODE {int data; data struct Dulnode *prior; precursor struct Dulnode *next;
Successor}dulnode,*dulinklist;
Initializes a doubly linked list void initlist (Dulinklist &l) {int i = 0;
Dulinklist p,q;
Char initdate[10] = {1,2,3,4,5,6,7,8,9};
L = (dulinklist) malloc (sizeof (Dulnode));
L->next = NULL; L->prior = NULL;
Construction head Node P = L; for (i = 0;i < strlen(initdate); i++) {q = (dulinklist) malloc (sizeof (Dulnode)); Q->data = Initdate[i];
The resulting ASCII code of the input character, minus 30H becomes the desired number, hexadecimal 30h is the decimal q->next = NULL;
Q->prior = p;
P->next = q;
p = q;
} printf ("Two-way linked list construction completed!\n");
}//print doubly linked list void printlist (Dulinklist &l) {dulinklist p;
if (L = = NULL) {printf ("The list does not exist, first initialize!\n");
} else if (L->next = = NULL) {p = l->next;
printf ("The list is empty!\n");
} else {p = l->next;
while (p) {printf ("%d", p->data);
p = p->next;
} printf ("\ n");
}}//reverse print bidirectional list void Printlistreverse (Dulinklist &l) {dulinklist p;
if (L = = NULL) {printf ("The list does not exist, first initialize!\n");
} else if (L->next = = NULL) {p = l->next;
printf ("The list is empty!\n");
} else {p = l->next; while (p->next) {p = P->next;
} while (P->prior) {printf ("%d", p->data);
p = p->prior;
} printf ("\ n");
}}//Find the list length int lengthdlist (dulinklist &l) {int i = 0;
if (L = = NULL) {printf ("The list does not exist, first initialize!\n");
} else {Dulinklist p = l->next;
while (p) {i++;
p = p->next;
}} return I;
}//Determine if the list is empty void Isemptylist (Dulinklist &l) {if (L = = NULL) {printf ("The list does not exist, initialize!\n first");
} else if (L->next = = null) {printf ("The list is empty!\n");
} else {printf ("linked list non-empty!\n");
}}//Put the doubly-linked list empty void Clearlist (Dulinklist &l) {if (l==null) {printf ("The list does not exist, first initialize!\n");
} else {dulinklist p,q; p = q = l->next;
is P, Q points to the first element l->next = NULL;
while (p)//Free up element by memory {p = p->next;
Free (q); Q = p;
}}}//delete the doubly linked list void destroylist (Dulinklist &l) {clearlist (L);
Free (L);
L = NULL;
}//Insert element M void Insertelmlist (Dulinklist &l) {int i,m in the doubly linked list after the first position;
printf ("Input inserted element: \ n");
scanf ("%d", &m);
printf ("input inserted position: \ n");
scanf ("%d", &i);
Dulinklist p,q;
p = L;
int j = 0;
if (L = = NULL) {printf ("The list does not exist, first initialize!\n");
} else if (L->next = = null) {printf ("The linked list is empty, please initialize and then insert data Operation!\n");
} else if (i<1 | | i>lengthdlist (L) +1) {printf ("Insertion position error!\n");
} else {while (j<i) {p = p->next;
j + +;
} if (j = = Lengthdlist (L))//If you insert m {q = (dulinklist) malloc (sizeof (Dulnode)) after the last element;
Q->data = m;
Q->next = NULL;
Q->prior = p;
P->next = q; } else {q = (dulinklist) malloc (sizeof (Dulnode));
Q->data = m;
Q->next = p->next;
P->next->prior = q;
P->next = q;
Q->prior = p;
}}}//delete the I element in the doubly linked list void delelmlist (Dulinklist &l) {int i;
printf ("Enter the location to delete:");
scanf ("%d", &i);
int j = 0;
Dulinklist p = L;
if (L = = NULL) {printf ("The list does not exist, first initialize!\n");
} else if (i<1 | | i>lengthdlist (L)) {printf ("the deleted position does not exist!\n");
} else {while (j<i) {p = p->next;
j + +;
} if (j = = Lengthdlist (L)) {p->prior->next = NULL;
Free (p);
} else {p->prior->next = p->next;
P->next->prior = p->prior;
Free (p);
}}} int main () {int i;
Dulinklist L = NULL;
Help ();
Initialize the doubly linked list initlist (L);
printf ("Please enter the operation:"); scanf ("%d", &amP;i);
while (0! = i) {switch (i) {case print_list:printlist (L);
Break
Case Print_list_reve:printlistreverse (L);
Break
Case list_len:printf ("linked list length:%d\n", Lengthdlist (L));
Break
Case Is_null:isemptylist (L);
Break
Case Clear_list:clearlist (L);
Break
Case Insert_eml_list:insertelmlist (L);
Break
Case Delete_eml_list:delelmlist (L);
Break
Case Dest_list:destroylist (L);
Break
default:printf ("Input error, please re-enter!\n");
Break
} help ();
printf ("Please enter the operation:");
scanf ("%d", &i);
} if (0 = = i) {printf ("program exits ... \ n");
} return 0;
}