首先来看示意图
其实可以看到双向链表比单向链表可以更快的访问到前置元素 但是需要更多的空间 也就是我们拿空间换取了时间
插入过程
首先是插入头结点
在其他位置插入节点
#ifndef DATAELEMENT_H_INCLUDED
#define DATAELEMENT_H_INCLUDED
#define MAX_SIZE 255
#define TRUE 1
#define FALSE 0
//1、定义数据元素
//typedef int ElementType;
/*
* datas = {{1, ""}, {2, ""}, {3, ""}};
*/
typedef struct{
int id;
char * name;
}ElementType;
#endif // DATAELEMENT_H_INCLUDED
#ifndef DOUBLYLINKLIST_H_INCLUDED
#define DOUBLYLINKLIST_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include "DataElement.h"
/** 双向链表的结点,包含一个数据域,两个指针域 */
typedef struct DoublyNode{
ElementType data;
struct DoublyNode * prev; //指向前缀结点
struct DoublyNode * next; //指向后继结点
}DoublyNode;
/** 双向链表 */
typedef struct DoublyLinkList{
int length;
DoublyNode * next;
}DoublyLinkList;
/** 向双向链表中的指定位置插入元素 */
void InsertDoublyLinkList(DoublyLinkList * dlList, int pos, ElementType element);
/** 删除并返回双向链表指定位置的元素 */
ElementType DeleteDoubyLinkList(DoublyLinkList * dlList, int pos);
/** 返回双向链表中指定位置的元素值 */
ElementType GetDoublyLinkListElement(DoublyLinkList * dlList, int pos);
/** 返回双向链表中某个结点的前置结点指针 */
DoublyNode * GetDoublyPrveNode(DoublyNode * node);
void PrintDoublyLinkList(DoublyLinkList * dlList);
#endif // DOUBLYLINKLIST_H_INCLUDED
#include "DoublyLinkList.h"
/** 向双向链表中的指定位置插入元素 */
void InsertDoublyLinkList(DoublyLinkList * dlList, int pos, ElementType element){
//创建空结点
DoublyNode * node = (DoublyNode*)malloc(sizeof(DoublyNode));
node->data = element;
node->prev = NULL;
node->next = NULL;
//在第一个位置插入结点
if(pos == 1){
//需要判断插入第一个位置并且插入时链表的长度为0
if(dlList->length == 0){
dlList->next = node;
dlList->length++;
return;
}
node->next = dlList->next;//对头节点和第一个元素进行操作
dlList->next = node;
node->next->prev = node;
dlList->length++;
return;
}
DoublyNode * currNode = dlList->next;
for(int i = 1; currNode && i < pos - 1; i++){
currNode = currNode->next;
}
if(currNode){
node->prev = currNode;
if(currNode->next){//如果前缀结点非空(因为空就表示没有后继结点了)
//将插入位置处的前缀结点指向新结点
currNode->next->prev = node;
}
node->next = currNode->next;
currNode->next = node;
dlList->length++;
}
}
/** 删除并返回双向链表指定位置的元素 */
ElementType DeleteDoubyLinkList(DoublyLinkList * dlList, int pos){
ElementType element;
element.id = -999;
if(pos == 1){
DoublyNode * node = dlList->next;
if(node){
element = node->data;
dlList->next = node->next;
if(node->next){
//如果有第二个结点,那么设置第二个节点的前缀结点为null
node->next->prev = NULL;
}
free(node);
dlList->length--;
}
return element;
}
DoublyNode * node = dlList->next;
for(int i = 1; node && i < pos; i++){
node = node->next;
}
if(node){
element = node->data;
if(node->next){
node->next->prev = node->prev;
}
node->prev->next = node->next;
free(node);
dlList->length--;
}
return element;
}
/** 返回双向链表中指定位置的元素值 */
ElementType GetDoublyLinkListElement(DoublyLinkList * dlList, int pos){
DoublyNode * node = dlList->next;
for(int i = 1; node && i < pos; i++){
node = node->next;
}
return node->data;
}
/** 返回双向链表中某个结点的前置结点指针 */
DoublyNode * GetDoublyPrveNode(DoublyNode * node){
if(node)
return node->prev;
return NULL;
}
void PrintDoublyLinkList(DoublyLinkList * dlList){
DoublyNode * node = dlList->next;
if(!node || dlList->length == 0){
printf("链表为空,没有内容可以打印!\n");
dlList->length = 0;
return;
}
for(int i = 0; i < dlList->length; i++){
printf("%d\t%s\n", node->data.id, node->data.name);
node = node->next;
}
}