数据结构--带头双向循环链表的基本功能实现

带头双向循环链表 : 是一种无死角链表, 是链表的一种,带有头结点, 其次它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点 , 且它的头指向尾 , 尾指向头 , 是循环的 , 是双向的 , 是带头结点的 ,

基本结构如下图所示 :          

                    

List.h

#pragma once
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <assert.h>
typedef int LTDataType;

//链表结构体
typedef struct ListNode
{
	struct ListNode* _next;
	struct ListNode* _prev;
	LTDataType _data;
}ListNode;

typedef struct List
{
	struct ListNode* _head;
}List;

//初始化链表
void ListInit(List* lt);
//销毁链表
void ListDestory(List* lt);
//头插
void ListPushFront(List* lt, LTDataType x);
//尾插
void ListPushBack(List* lt, LTDataType x);
//头删
void ListPopFront(List* lt);
//尾删
void ListPopBack(List* lt);
//申请节点
ListNode* BuyListNode();
//查找节点
ListNode* ListFind(List* lt, LTDataType x);
//指定位置插入
void ListInsert(ListNode* pos, LTDataType x);
//指定位置删除
void ListErase(ListNode* pos);
//链表大小
int ListSize(List* lt);
//判断链表是否为空
int ListEmpty(List* lt);
//打印链表
void ListPrint(List* lt);

 List.c

#include "List.h"
//初始化链表
void ListInit(List* lt)
{
	//创建头结点
	lt->_head = BuyListNode();
	lt->_head->_next = lt->_head;
	lt->_head->_prev = lt->_head;
}
//销毁链表
void ListDestory(List* lt)
{
	ListNode *del,*ret;
	assert(lt);
	del = lt->_head->_next;
	while (del == lt->_head)
	{
		ret = del;
		free(ret);
		ret = NULL;
		del = del->_next;
	}
	free(del);
	del = NULL;
}
//头插
void ListPushFront(List* lt, LTDataType x)
{
	assert(lt);
	//相当于在头结点后面插入
	ListInsert(lt->_head->_next, x);
}
//尾插
void ListPushBack(List* lt, LTDataType x)
{
	assert(lt);
	//相当于在头结点前面插入
	ListInsert(lt->_head->_prev, x);
}
//头删
void ListPopFront(List* lt)
{
	assert(lt);
	//相当于删除头结点后面的元素
	ListErase(lt->_head->_prev);
}
//尾删
void ListPopBack(List* lt)
{
	assert(lt);
	//相当于删除头结点前面的元素
	ListErase(lt->_head->_next);
}
//申请节点
ListNode* BuyListNode()
{
	ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
	//断言,空间是否开辟成功
	assert(newNode);
	newNode->_next = NULL;
	newNode->_prev = NULL;
	return newNode;
}
//查找节点
ListNode* ListFind(List* lt, LTDataType x)
{
	ListNode * newNode;
	assert(lt);
	newNode = lt->_head;
	while (newNode->_next != lt->_head)
	{
		newNode=newNode->_next;
		if (newNode->_data == x)
			return newNode;
	}
	printf("要查找的数据 %d 不存在!\n",x);
	return NULL;
}
//指点位置插入
void ListInsert(ListNode* pos, LTDataType x)
{
	ListNode *prev;
	ListNode *newNode;
	if (!pos)
	{
		printf("数据 %d 插入失败!\n", x);
		return;
	}
	newNode = BuyListNode();
	newNode->_data = x;
	prev = pos->_prev;
	prev->_next = newNode;
	newNode->_prev = prev;
	newNode->_next = pos;
	pos->_prev = newNode;
}
//指点位置删除
void ListErase(ListNode* pos)
{
	ListNode *prev;
	prev = pos->_prev;
	prev->_next = pos->_next;
	pos->_next->_prev = prev;
	free(pos);
	pos = NULL;
}
//链表大小
int ListSize(List* lt)
{
	ListNode *cur;
	int size = 0;
	assert(lt);
	assert(lt);
	cur = lt->_head;
	while (cur->_next != lt->_head)
	{
		cur = cur->_next;
		size++;
	}
	return size;
}
//判断链表是否为空
int ListEmpty(List* lt)
{
	assert(lt);
	//为空返回0,非空返回1
	return lt->_head->_next == lt->_head->_prev ? 0 : 1;
}
//打印链表
void ListPrint(List* lt)
{
	ListNode *cur;
	assert(lt);
	cur = lt->_head;
	printf("链表中的数据为: ");
	while (cur->_next != lt->_head)
	{
		printf("%d ", cur->_next->_data);
		cur = cur->_next;
	}
	printf("\n");
}

test.c

#include "List.h"
int main()
{
	List lt;
	ListNode *cur;
	ListInit(&lt);
	ListPushBack(&lt, 1);
	ListPushBack(&lt, 2);
	ListPushBack(&lt, 3);
	ListPushBack(&lt, 4);
	cur = ListFind(&lt, 3);
	ListErase(cur);
	cur = ListFind(&lt, 4);
	ListInsert(cur, 5);
	printf("链表的长度为: %d\n", ListSize(&lt));
	ListPrint(&lt);
	ListDestory(&lt);
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/ds19980228/article/details/81813670