数据结构与算法:双向链表
2016-11-05 18:11
656 查看
与单向链表相比,双向链表拥有两个指针域,一个指向直接前趋,一个指向直接后继。
由图:
双向链表的结点也由数据域和指针域组成;
结点之间通过指针域相连,Prev指针指向直接前趋,Next指针指向直接后继;
头指针指向首元结点;
首元结点的Prev指针为空指针,尾结点的Next指针为空指针。
插入——在链表开头插入一个结点
——在链表尾部插入一个结点
——在链表中某个结点后插入一个结点
删除——删除第一个结点
——删除最后一个结点
——删除指定结点后的一个结点
遍历——顺序遍历
——倒序遍历
以下代码展示了如何在双向链表开头插入一个结点:
下面的代码展示了如何删除第一个结点:
代码如下:
各种操作的C语言实现如下:
编译运行结果如下:
双向链表的表示
由图:双向链表的结点也由数据域和指针域组成;
结点之间通过指针域相连,Prev指针指向直接前趋,Next指针指向直接后继;
头指针指向首元结点;
首元结点的Prev指针为空指针,尾结点的Next指针为空指针。
基本操作
插入——在链表开头插入一个结点——在链表尾部插入一个结点
——在链表中某个结点后插入一个结点
删除——删除第一个结点
——删除最后一个结点
——删除指定结点后的一个结点
遍历——顺序遍历
——倒序遍历
插入操作
以下代码展示了如何在双向链表开头插入一个结点://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; //mark old last node as prev of new link link->prev = last; } //point last to new last node last = link; }
C语言实现
各种操作的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) {
//print data
printf("(%d,%d) ",ptr->key,ptr->data);
//move to next item
ptr = ptr ->prev;
printf(" ");
}
printf(" ]");
}
//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; //mark old last node as prev of new link link->prev = last; } //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
if(current->next == NULL) {
return NULL;
} else {
//store reference to current link
previous = current;
//move to next link
current = current->next;
}
}
//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) {
//if it is last node
if(current->next == NULL) {
return false;
} else {
//move to next link
current = current->next;
}
}
//create a link
struct node *newLink = (struct node*) malloc(sizeof(struct node));
newLink->key = key;
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;
}
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) (4,13) (3,30) (2,20) ] List , after delete key(4) : [ (5,40) (4,13) (3,30) (2,20) ]
相关文章推荐
- 数据结构与算法_链表2_双向链表
- [数据结构与算法]双向链表
- 算法学习之数据结构之双向链表
- 数据结构与算法之双向链表
- 数据结构与算法 2、单向/双向链表
- 数据结构与算法笔记 lesson8 双向链表
- 数据结构与算法之双向链表 <二>
- 数据结构与算法(C语言版)__双向链表
- 数据结构与算法--双向链表
- 数据结构与算法----双向链表
- linux 内核常用数据结构及算法——list(循环双向链表)
- 数据结构之静态链表和双向循环链表
- php学习第一章:PHP基础语法(三)数据结构与算法:2、单向链表
- 数据结构与算法之—链表(二) 有序单链表合并
- 数据结构与算法——链表
- 数据结构之单链表取第i个元素的算法
- [数据结构算法学习] 单向链表
- 算法学习之数据结构之链表是否相交,链表是否存在环
- 数据结构课程设计-----用C#实现双向链表
- 数据结构与算法面试题汇编(1)- 链表的操作与应用