【数据结构】 模拟实现带头双向循环链表
引言:在前不久对单链表做了详细了解和代码实现后,今天我们继续来探索链表中最常用到之一的双向循环链表。
带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了。
结构图如下:
代码实现如下:
List.h
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<malloc.h>
#include<assert.h>
#include<stdlib.h>
typedef int SLTDataType;
typedef struct SListNode
{
SLTDataType _data;
struct SListNode* _next;
struct SListNode* _prev;
}SListNode;
typedef struct SList
{
struct SListNode* _head;
}SList;
void SListInit(SList* plt);//初始化
void SListDestory(SList* plt);//销毁
SListNode* BuySListNode(SLTDataType x);//申请新节点
void SListPushFront(SList* plt, SLTDataType x);//头插
void SListPopfront(SList* plt);//头删
void SListPushBack(SList* plt, SLTDataType x);//尾插
void SListPopBack(SList*plt);//尾删
SListNode* SListFind(SList* plt, SLTDataType x);//查找
void SListInsertAfter(SListNode* pos, SLTDataType x);//在pos后插入
void SListNodeErase(SList*plt, SListNode* pos);//在pos前面插入
void SListNodeRemove(SList*plt, SLTDataType x);//移动数据
void SListPrint(SList* plt);
void TestSList();
List.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"List.h"
void SListInit(SList* plt)//初始化
{
assert(plt);
SListNode* head = BuySListNode(-1);
head->_next = head;
head->_next = head;
plt->_head = head;
}
void SListDestory(SList* plt)
{
assert(plt);
SListNode* cur = plt->_head->_next;
SListNode* head = plt->_head;
SListNode* next = NULL;
while (cur != head)
{
next = cur->_next;
free(cur);
cur = next;
}
free(plt->_head);
plt->_head = NULL;
}
SListNode* BuySListNode(SLTDataType x)
{
SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
newnode->_next = NULL;
newnode->_prev = NULL;
newnode->_data = x;
return newnode;
}
void SListPushFront(SList* plt, SLTDataType x)//头插
{
assert(plt);
SListNode* head = plt->_head;
SListNode* next = head->_next;
SListNode* newnode = BuySListNode(x);
head->_next = newnode;
newnode->_prev = head;
newnode->_next = next;
next->_prev = newnode;
}
void SListPopfront(SList* plt)//头删
{
assert(plt && plt->_head->_next);
SListNode* head = plt->_head;
SListNode* cur = plt->_head->_next;
SListNode* next = cur->_next;
head->_next = next;
next->_prev = head;
free(cur);
}
void SListPushBack(SList* plt, SLTDataType x)//尾插
{
assert(plt && plt->_head->_next);
SListNode* head = plt->_head;
SListNode* tail = head->_prev;
SListNode* newnode = BuySListNode(x);
tail->_next = newnode;
newnode->_prev = tail;
newnode->_next = head;
head->_prev = newnode;
}
void SListPopBack(SList*plt)//尾删
{
assert(plt&& plt->_head->_next);
SListNode* head = plt->_head;
SListNode* tail = head->_prev;
SListNode* prev = tail->_prev;
free(tail);
prev->_next = head;
head->_prev = prev;
}
SListNode* SListFind(SList* plt, SLTDataType x)
{
assert(plt);
SListNode* head = plt->_head;
SListNode* cur = head->_next;
while (cur != head)
{
if (cur->_data==x)
{
return cur;
}
cur = cur->_next;
}
return NULL;
}
//在pos前插入
void SListInsertAfter(SListNode* pos, SLTDataType x)
{
assert(pos);
SListNode* prev = pos->_prev;
SListNode* newnode = BuySListNode(x);
prev->_next = newnode;
newnode->_prev = prev;
newnode->_next = pos;
pos->_prev = newnode;
}
void SListNodeErase(SList*plt, SListNode* pos)
{
assert(plt);
SListNode* prev = pos->_prev;
SListNode* next = pos->_next;
free(pos);
prev->_next = next;
next->_prev = prev;
}
void SListNodeRemove(SList*plt, SLTDataType x)
{
SListNode* pos = SListFind(plt, x);
if (pos)
{
SListNodeErase(plt, pos);
}
}
void SListPrint(SList* plt)
{
assert(plt);
SListNode* cur = plt->_head->_next;
SListNode* head = plt->_head;
printf("<=head=>");
while (cur !=head)
{
printf("<=%d=>", cur->_data);
cur = cur->_next;
}
printf("\n");
}
void TestSList()
{
SList lt;
SListInit(<);
SListPushFront(<, 5);
SListPushFront(<, 4);
SListPushFront(<, 3);
SListPushFront(<, 2);
SListPushFront(<, 1);
SListPrint(<);
SListPopfront(<);
SListPrint(<);
SListPopBack(<);
SListPrint(<);
SListPushBack(<,8);
SListPrint(<);
SListFind(<, 3);
SListNode* pos = NULL;
pos = SListFind(<, 3);
SListInsertAfter(pos, 7);
SListPrint(<);
SListNodeErase(<, pos);
SListPrint(<);
SListNodeRemove(<, 4);
SListPrint(<);
}
Test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"List.h"
int main()
{
TestSList();
system("pause");
return 0;
}