前面的博客中我们实现了不带头结点、不带环的单向链表,其操作比较复杂,且实际应用相对较少。那今天我们来实现一下带头节点、带环的双向链表,相对来说操作比较简单,而且实际应用性较强。
声明:
dlinklist.h
#pragma once
//带头节点、带环的双向链表
typedef char DLinkType;
typedef struct DLinkNode
{
DLinkType data;
struct DLinkNode* prev;
struct DLinkNode* next;
}DLinkNode;
void DLinkListInit(DLinkNode** phead);//初始化
void DLinkListDestroy(DLinkNode** phead);//销毁
void DLinkListPushBack(DLinkNode* phead,DLinkType value);//尾插
void DLinkListPopBack(DLinkNode* phead);//尾删
void DLinkListPushFront(DLinkNode* phead,DLinkType value);//头插
void DLinkListPopFront(DLinkNode* phead);//头删
DLinkNode* DLinkListFind(DLinkNode* phead,DLinkType to_find);//查找元素
//在pos位置后面插入元素
void DLinkListInsert(DLinkNode* phead,DLinkNode* pos,DLinkType to_insert);
//在pos之前插入元素
void DLinkListInsertBefore(DLinkNode* phead,DLinkNode* pos,DLinkType to_insert);
//删除指定位置的元素
void DLinkListErase(DLinkNode* phead,DLinkNode* pos);
//删除指定值的元素
void DLinkListRemove(DLinkNode* phead,DLinkType to_remove);
//删除指定元素的所有值
void DLinkListRemoveAll(DLinkNode* phead,DLinkType to_remove);
//求双向链表的大小
size_t DLinkListSize(DLinkNode* phead);
//判断双向链表是否为空,是空链表返回1,否则返回0
int DLinkListEmpty(DLinkNode* phead);
具体函数实现及测试代码:
dlinklist.c
#include<stddef.h>
#include<stdlib.h>
#include"dlinklist.h"
#include<stdio.h>
DLinkNode* CreateDLinkNode(DLinkType value)
{
DLinkNode* new_node =(DLinkNode*)malloc(sizeof(DLinkNode));
new_node->data = value;
new_node->prev = new_node;
new_node->next= new_node;
return new_node;
}
void DLinkListInit(DLinkNode** phead)
{
if(phead == NULL)
{
return; //非法输入
}
*phead = CreateDLinkNode(0);
}
void DestroyNode(DLinkNode* node)
{
free(node);
}
void DLinkListDestroy(DLinkNode** phead)
{
if(phead == NULL)
{
return; //非法输入
}
DLinkNode* cur = (*phead)->next;
while(cur != *phead)
{
DLinkNode* next = cur->next;
DestroyNode(cur);
cur = next;
}
*phead = NULL;
}
void DLinkListPushBack(DLinkNode* phead,DLinkType value)
{
if(phead == NULL)
{
return; //非法输入
}
DLinkNode* new_node = CreateDLinkNode(value);
DLinkNode* tail = phead->prev;
tail->next = new_node;
new_node->prev = tail;
phead->prev = new_node;
new_n