双向链表的结点里包含一个指向上一个元素的pre指针,一个指向下一个元素的next指针,而要实现循环只需要将头节点的pre指向最后一个节点,而最后后一个节点的next指向头节点。下面是代码实现部分。
首先时头文件部分
#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
//熟悉双向链表的结构,并实现带头结点的双向循环链表的以下基本操作:
typedef int DLDataType;
typedef struct DListNode
{
struct DListNode* _pNext;
struct DListNode* _pPre;
DLDataType _data;
}DLNode;
// 初始化双向链表
void DListInit(DLNode** pHead);
// 尾插
void DListPushBack(DLNode* pHead, DLDataType data);
// 尾删
void DListPopBack(DLNode* pHead);
// 头插
void DListPushFront(DLNode* pHead, DLDataType data);
// 头删
void DListPopFront(DLNode* pHead);
// 在链表中查找值为data的节点,找到返回节点的位置
DLNode* DListFind(DLNode* pHead, DLDataType data);
// 在pos位置(插入成功后新节点实际在pos前)插入值为data的元素
void DListInsert(DLNode* pos, DLDataType data);
// 删除pos位置的节点
void DListErase(DLNode* pos);
// 将链表中的所有节点清空
void DListClear(DLNode* pHead);
// 销毁链表
void DListDestroy(DLNode** pHead);
接下来是各个函数的功能实现部分
#define _CRT_SECURE_NO_WARNINGS
#include"Dlist.h"
// 初始化双向链表
void DListInit(DLNode** pHead)
{
DLNode* node = (DLNode*)malloc(sizeof(DLNode));
node->_pNext = node;
node->_pPre = node;
pHead = node;
}
// 尾插
void DListPushBack(DLNode* pHead, DLDataType data)
{
assert(pHead);
DLNode* node = (DLNode*)malloc(sizeof(DLNode));
node->_data = data;
node->_pNext = pHead;
node->_pPre = pHead->_pPre;
pHead->_pPre = node;
}
// 尾删
void DListPopBack(DLNode* pHead)
{
assert(pHead);
DLNode* node = (DLNode*)malloc(sizeof(DLNode));
node = pHead->_pPre->_pPre;
free(pHead->_pPre);
pHead->_pPre = node;
node->_pNext = pHead;
}
// 头插
void DListPushFront(DLNode* pHead, DLDataType data)
{
assert(pHead);
DLNode* node = (DLNode*)malloc(sizeof(DLNode));
node->_data = data;
node->_pNext = pHead->_pNext;
node->_pPre = pHead;
pHead->_pNext = node;
}
// 头删
void DListPopFront(DLNode* pHead)
{
assert(pHead);
DLNode* node = (DLNode*)malloc(sizeof(DLNode));
node = pHead->_pNext->_pNext;
free(pHead->_pNext);
pHead->_pNext = node;
node->_pPre = pHead;
}
// 在链表中查找值为data的节点,找到返回节点的位置
DLNode* DListFind(DLNode* pHead, DLDataType data)
{
assert(pHead);
DLNode* cur;
for (cur = pHead; cur->_pNext != pHead; cur = cur->_pNext)
{
if (cur->_data == data)
{
return cur;
}
}
}
// 在pos位置(插入成功后新节点实际在pos前)插入值为data的元素
void DListInsert(DLNode* pos, DLDataType data)
{
DLNode* node = (DLNode*)malloc(sizeof(DLNode));
node->_data = data;
node->_pNext = pos;
node->_pPre = pos->_pPre;
pos->_pPre->_pNext = node;
pos->_pPre = node;
}
// 删除pos位置的节点
void DListErase(DLNode* pos)
{
DLNode* nodep;
DLNode* noden;
pos->_pPre = nodep;
pos->_pNext = noden;
free(pos);
nodep->_pNext = noden;
noden->_pPre = nodep;
}
// 将链表中的所有节点清空
void DListClear(DLNode* pHead)
{
assert(pHead);
DLNode* node = pHead->_pNext;
DLNode* node1 = pHead->_pNext;
while (node != pHead)
{
node = node->_pNext;
free(node1);
node1 = node;
}
pHead->_pNext = pHead;
pHead->_pPre = pHead;
}
// 销毁链表
void DListDestroy(DLNode* pHead)
{
DLNode* node = pHead->_pNext;
DLNode* node1 = pHead->_pNext;
while (node != pHead)
{
node = node->_pNext;
free(node1);
node1 = node;
}
free(pHead);
pHead = NULL;
}