双向链表(双链表)是链表的一种,和单链表一样,双链表也是由节点组成,它的每个数据结点中都有两个指针,分别指向后继(Next)和前驱(Prev)。
双链表表示

根据上面的说明,以下是要考虑的重点。
双向链表包含一个名为first和last的链接元素。
每个链接包含一个数据字段(data)和两个链接字段,分别称为next和prev。
每个链接都使用其Next链接指向下一个链接节点。
每个链接都使用其prev链接指向上一个链接节点。
最后一个链接的链接为NULL,以表示列表已结尾。
插入操作
以下代码演示了在双向链表开头的插入操作。
//insert link at the first location void insertFirst(int key, int data) {//create a link struct node link = (struct node) malloc(sizeof(struct node)); link->key = key; link->data = data;
if(isEmpty()) { //make it the last link last = link; } else { //update first prev link head->prev = link; }
//point it to old first link link->next = head;
//point first to new first link head = link; }
删除操作
以下代码演示了双向链表开头的删除操作。
//delete first item struct node* deleteFirst() {//save reference to first link struct node *tempLink = head;
//if only one link if(head->next == NULL) { last = NULL; } else { head->next->prev = NULL; }
head = head->next;
//return the deleted link return tempLink; }
插入到链尾
以下代码演示了在双链表的最后位置的插入操作。
//insert link at the last location
void insertLast(int key, int data) {
//create a link
struct node link = (struct node) malloc(sizeof(struct node));
link->key = key;
link->data = data;
if(isEmpty()) {
//make it the last link
last = link;
} else {
//make link a new last link
last->next = link;
</span><span class="com">//mark old last node as prev of new link</span><span class="pln">
link</span><span class="pun">-></span><span class="pln">prev </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">last</span><span class="pun">;</span><span class="pln">
}
//point last to new last node
last = link;
}
C语言代码实现
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
struct node {
int data;
int key;
struct node next;
struct node prev;
};
//this link always point to first Link
struct node *head = NULL;
//this link always point to last Link
struct node *last = NULL;
struct node *current = NULL;
//is list empty
bool isEmpty() {
return head == NULL;
}
int length() {
int length = 0;
struct node *current;
for(current = head; current != NULL; current = current->next){
length++;
}
return length;
}
//display the list in from first to last
void displayForward() {
//start from the beginning
struct node *ptr = head;
//navigate till the end of the list
printf("\n[ ");
while(ptr != NULL) {
printf("(%d,%d) ",ptr->key,ptr->data);
ptr = ptr->next;
}
printf(" ]");
}
//display the list from last to first
void displayBackward() {
//start from the last
struct node *ptr = last;
//navigate till the start of the list
printf("\n[ ");
while(ptr != NULL) {
</span><span class="com">//print data</span><span class="pln">
printf</span><span class="pun">(</span><span class="str">"(%d,%d) "</span><span class="pun">,</span><span class="pln">ptr</span><span class="pun">-></span><span class="pln">key</span><span class="pun">,</span><span class="pln">ptr</span><span class="pun">-></span><span class="pln">data</span><span class="pun">);</span><span class="pln">
</span><span class="com">//move to next item</span><span class="pln">
ptr </span><span class="pun">=</span><span class="pln"> ptr </span><span class="pun">-></span><span class="pln">prev</span><span class="pun">;</span><span class="pln">
}
}
//insert link at the first location
void insertFirst(int key, int data) {
//create a link
struct node link = (struct node) malloc(sizeof(struct node));
link->key = key;
link->data = data;
if(isEmpty()) {
//make it the last link
last = link;
} else {
//update first prev link
head->prev = link;
}
//point it to old first link
link->next = head;
//point first to new first link
head = link;
}
//insert link at the last location
void insertLast(int key, int data) {
//create a link
struct node link = (struct node) malloc(sizeof(struct node));
link->key = key;
link->data = data;
if(isEmpty()) {
//make it the last link
last = link;
} else {
//make link a new last link
last->next = link;
</span><span class="com">//mark old last node as prev of new link</span><span class="pln">
link</span><span class="pun">-></span><span class="pln">prev </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">last</span><span class="pun">;</span><span class="pln">
}
//point last to new last node
last = link;
}
//delete first item
struct node* deleteFirst() {
//save reference to first link
struct node *tempLink = head;
//if only one link
if(head->next == NULL){
last = NULL;
} else {
head->next->prev = NULL;
}
head = head->next;
//return the deleted link
return tempLink;
}
//delete link at the last location
struct node deleteLast() {
//save reference to last link
struct node tempLink = last;
//if only one link
if(head->next == NULL) {
head = NULL;
} else {
last->prev->next = NULL;
}
last = last->prev;
//return the deleted link
return tempLink;
}
//delete a link with given key
struct node* delete(int key) {
//start from the first link
struct node current = head;
struct node previous = NULL;
//if list is empty
if(head == NULL) {
return NULL;
}
//navigate through list
while(current->key != key) {
//if it is last node
</span><span class="kwd">if</span><span class="pun">(</span><span class="pln">current</span><span class="pun">-></span><span class="kwd">next</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> NULL</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> NULL</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="com">//store reference to current link</span><span class="pln">
previous </span><span class="pun">=</span><span class="pln"> current</span><span class="pun">;</span><span class="pln">
</span><span class="com">//move to next link</span><span class="pln">
current </span><span class="pun">=</span><span class="pln"> current</span><span class="pun">-></span><span class="kwd">next</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
}
//found a match, update the link
if(current == head) {
//change first to point to next link
head = head->next;
} else {
//bypass the current link
current->prev->next = current->next;
}
if(current == last) {
//change last to point to prev link
last = current->prev;
} else {
current->next->prev = current->prev;
}
return current;
}
bool insertAfter(int key, int newKey, int data) {
//start from the first link
struct node *current = head;
//if list is empty
if(head == NULL) {
return false;
}
//navigate through list
while(current->key != key) {
</span><span class="com">//if it is last node</span><span class="pln">
</span><span class="kwd">if</span><span class="pun">(</span><span class="pln">current</span><span class="pun">-></span><span class="kwd">next</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> NULL</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="com">//move to next link</span><span class="pln">
current </span><span class="pun">=</span><span class="pln"> current</span><span class="pun">-></span><span class="kwd">next</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
}
//create a link
struct node newLink = (struct node) malloc(sizeof(struct node));
newLink->key = newKey;
newLink->data = data;
if(current == last) {
newLink->next = NULL;
last = newLink;
} else {
newLink->next = current->next;
current->next->prev = newLink;
}
newLink->prev = current;
current->next = newLink;
return true;
}
void main() {
insertFirst(1,10);
insertFirst(2,20);
insertFirst(3,30);
insertFirst(4,1);
insertFirst(5,40);
insertFirst(6,56);
printf("\nList (First to Last): ");
displayForward();
printf("\n");
printf("\nList (Last to first): ");
displayBackward();
printf("\nList , after deleting first record: ");
deleteFirst();
displayForward();
printf("\nList , after deleting last record: ");
deleteLast();
displayForward();
printf("\nList , insert after key(4) : ");
insertAfter(4,7, 13);
displayForward();
printf("\nList , after delete key(4) : ");
delete(4);
displayForward();
}
代码输出
List (First to Last): [ (6,56) (5,40) (4,1) (3,30) (2,20) (1,10) ]List (Last to first): [ (1,10) (2,20) (3,30) (4,1) (5,40) (6,56) ] List , after deleting first record: [ (5,40) (4,1) (3,30) (2,20) (1,10) ] List , after deleting last record: [ (5,40) (4,1) (3,30) (2,20) ] List , insert after key(4) : [ (5,40) (4,1) (7,13) (3,30) (2,20) ] List , after delete key(4) : [ (5,40) (4,13) (3,30) (2,20) ]