数据结构与算法:双向链表

来源:互联网 发布:linux内核编译教程 编辑:程序博客网 时间:2024/05/20 06:57

与单向链表相比,双向链表拥有两个指针域,一个指向直接前趋,一个指向直接后继。

双向链表的表示

由图:双向链表

  1. 双向链表的结点也由数据域和指针域组成;
  2. 结点之间通过指针域相连,Prev指针指向直接前趋,Next指针指向直接后继;
  3. 头指针指向首元结点;
  4. 首元结点的Prev指针为空指针,尾结点的Next指针为空指针。

基本操作

插入——在链表开头插入一个结点

        ——在链表尾部插入一个结点

        ——在链表中某个结点后插入一个结点

删除——删除第一个结点

        ——删除最后一个结点

        ——删除指定结点后的一个结点

遍历——顺序遍历

        ——倒序遍历

插入操作

以下代码展示了如何在双向链表开头插入一个结点:

//insert link at the first locationvoid 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 itemstruct 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 locationvoid 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 Linkstruct node *head = NULL;//this link always point to last Link struct node *last = NULL;struct node *current = NULL;//is list emptybool 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 lastvoid 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 firstvoid 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 locationvoid 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 locationvoid 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 itemstruct 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 locationstruct 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 keystruct 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) ]

 

1 0