1.双向链表的优点:双向链表的主要优点是对于任意给的结点,都可以很轻易的获取其前结点和后结点,其主要缺点是每个结点需要保存next和prev两个属性,因此需要更多的空间开销,同时结点的插入与删除操作也将更加耗时,因为需要操作更多的指向操作
2.双向链表的结构
(1)单个节点的结构:
(2)数据的结构:
(3)尾部插入节点:
(4)中间插入
3.双向链表的具体操作
#include "stdafx.h" #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> //节点结构 typedef struct LinkedList { struct LinkedList * prior; int data; struct LinkedList * next; }LinkedList, *PLinkedList; //双链表的创建函数 PLinkedList initLine(PLinkedList head); //输出双链表的函数 void Display(PLinkedList head); //插入节点 void InsertElem(PLinkedList head, int data); //删除指定节点 void DeleteElem(PLinkedList head, int data); int main() { //创建一个头指针 PLinkedList head = NULL; //调用链表创建函数 head = initLine(head); //输出创建好的链表 Display(head); //尾部插入一个节点 InsertElem(head, 10); Display(head); //删除尾部的节点 DeleteElem(head, 10); Display(head); //显示双链表的优点 printf("链表中第 4 个节点的直接前驱是:%d", head->next->next->next->prior->data); system("pause"); return 0; } void InsertElem(PLinkedList head, int data) { if (head == NULL){ printf("The list is empty. "); // 头结点为空,则无法插入 return; } PLinkedList tmpHead = head; // 创建一个临时的头结点指针 while (tmpHead->next!=NULL) { tmpHead = tmpHead->next; } if (tmpHead->next == NULL) { PLinkedList addition = (PLinkedList)malloc(sizeof(LinkedList)); _ASSERT(addition != NULL); addition->data = data; // 数据域赋值 addition->next = tmpHead->next; // 后向指针连接 tmpHead->next = addition; addition->prior = tmpHead; // 将插入结点的front 指向头结点 } } void DeleteElem(PLinkedList head, int data) { if (head == NULL){ printf("The list is empty. "); return; } PLinkedList tmpHead = head; while (tmpHead->next != NULL){ tmpHead = tmpHead->next; if (tmpHead->data == data) { //此节点为最后一个节点 if (tmpHead->next == NULL) { tmpHead->prior->next = NULL; // 将被删结点的上一个结点的next 指针指向 NULL tmpHead->prior->prior = head; // 将被删结点的上一个结点的prior指向头节点 } //删除中间节点 else { tmpHead->prior->next = tmpHead->next; // 将被删结点的上一个结点的next 指针指向 被删结点的下一个结点 tmpHead->next->prior = tmpHead->prior; // 将被删结点的下一个结点的 front 指针指向 被删结点的上一个结点 } break; } } free(tmpHead); // 释放内存 } PLinkedList initLine(PLinkedList head) { //创建一个首元节点,链表的头指针为head head = (PLinkedList)malloc(sizeof(LinkedList)); //对节点进行初始化 head->prior = NULL; head->next = NULL; head->data = 1; //声明一个指向首元节点的指针,方便后期向链表中添加新创建的节点 PLinkedList list = head; for (int i = 2; i <= 5; i++) { //创建新的节点并初始化 PLinkedList body = (PLinkedList)malloc(sizeof(LinkedList)); body->prior = NULL; body->next = NULL; body->data = i; //新节点与链表最后一个节点建立关系 list->next = body; body->prior = list; //list永远指向链表中最后一个节点 list = list->next; } //返回新创建的链表 return head; } void Display(PLinkedList head) { PLinkedList temp = head; while (temp) { //如果该节点无后继节点,说明此节点是链表的最后一个节点 if (temp->next == NULL) { printf("%d ", temp->data); } else{ printf("%d <-> ", temp->data); } temp = temp->next; } }