【数据结构】---模拟实现带头双向循环链表

【数据结构】 模拟实现带头双向循环链表

引言:在前不久对单链表做了详细了解和代码实现后,今天我们继续来探索链表中最常用到之一的双向循环链表。

模拟实现单链表

带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了。

结构图如下:【数据结构】---模拟实现带头双向循环链表_第1张图片
代码实现如下
List.h

#define _CRT_SECURE_NO_WARNINGS 1

#pragma once
#include
#include
#include
#include

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(&lt);
	SListPushFront(&lt, 5);
	SListPushFront(&lt, 4);
	SListPushFront(&lt, 3);
	SListPushFront(&lt, 2);
	SListPushFront(&lt, 1);
	
	SListPrint(&lt);
	SListPopfront(&lt);
	
	SListPrint(&lt);
	SListPopBack(&lt);
	
	SListPrint(&lt);
	SListPushBack(&lt,8);
	
	SListPrint(&lt);

	SListFind(&lt, 3);


	SListNode* pos = NULL;
	pos = SListFind(&lt, 3);

	SListInsertAfter(pos, 7);
	SListPrint(&lt);

	SListNodeErase(&lt, pos);
	SListPrint(&lt);

	SListNodeRemove(&lt, 4);
	SListPrint(&lt);
}

Test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"List.h"
int main()
{
	TestSList();
	system("pause");
	return 0;
}

【数据结构】---模拟实现带头双向循环链表_第2张图片

你可能感兴趣的:(数据结构,模拟实现带头双向循环链表)