带头结点的双向循环链表的基本操作

定义与声明

typedef int DataType;


typedef struct DListNode
{
	DataType data;
	struct DListNode* Pre;
	struct DListNode* Next;
}Node;

void DListInit(Node** pHead);//初始化
void DListPushBack(Node* p, DataType data);//尾插
void DListPopBack(Node* p);//尾删
void DListPushFront(Node* p, DataType data);//头插
void DListPopFront(Node* p);//头删
void DListInsert(Node* pos,DataType data);//在pos地址结点之前插入新的值为data的结点
Node* DListFind(Node* p,DataType data);//找到值为data的结点返回结点的地址,没有返回NULL
void DListErase(Node* pos);//删除pos地址的结点
void DListRemove(Node* p, DataType data);//删除链表中值为data的第一个结点
void DListRemoveAll(Node* p, DataType data);//删除链表中所有值为data结点
void ListDestory(Node** p);//销毁链表

函数实现

#include"DList.h"
Node* BuyNewNode(DataType data)
{
	Node* NewNode = (Node*)malloc(sizeof(Node));
	if (NULL == NewNode)
	{
		assert(0);
		return NULL;
	}
	NewNode->Pre = NULL;
	NewNode->Next = NULL;
	NewNode->data = data;
	return NewNode;
}
void DListInit(Node** pHead)
{
	assert(pHead);
	Node* New = BuyNewNode(0);
	New->Next = New;
	New->Pre = New;
	*pHead = New;
}
void DListPushBack(Node* p, DataType data)
{
	assert(p);
	Node* NewNode = BuyNewNode(data);
	NewNode->Next = p;
	NewNode->Pre = p->Pre;
	p->Pre->Next = NewNode;
	p->Pre = NewNode;

}
void DListPopBack(Node* p)
{
	assert(p);
	if (p->Next == p)
	{
		return;
	}
	else
	{
		p->Pre = p->Pre->Pre;
		free(p->Pre->Next);
		p->Pre->Next = p;
	}
}
void DListPushFront(Node* p, DataType data)
{
	assert(p);
	Node* NewNode = BuyNewNode(data);
	NewNode->Next = p->Next;
	NewNode->Pre = p;
	p->Next->Pre = NewNode;
	p->Next = NewNode;
}
void DListPopFront(Node* p)
{
	assert(p);
	Node* Del = p->Next;
	p->Next->Next->Pre = p;
	p->Next = p->Next->Next;
	free(Del);
	Del = NULL;
}
Node* DListFind(Node* p,DataType data)
{
	assert(p);
	Node* cur = p->Next;
	while (cur != p)
	{
		if (cur->data == data)
		{
			return cur;
		}
		cur = cur->Next;
	}
	return NULL;
}
void DListInsert(Node* pos, DataType data)
{
	assert(pos);
	Node* NewNode = BuyNewNode(data);
	NewNode->Next = pos;
	NewNode->Pre = pos->Pre;
	pos->Pre->Next = NewNode;
	pos->Pre = NewNode;
}
void DListErase(Node* pos)
{
	assert(pos);
	pos->Next->Pre = pos->Pre;
	pos->Pre->Next = pos->Next;
	free(pos);
	pos = NULL;
}
void DListRemove(Node* p, DataType data)
{
	assert(p);
	Node *cur = p->Next;
	while (cur->Next!=p)
	{
		if (cur->data == data)
		{
			break;
		}
		cur = cur->Next;
	}
	cur->Next->Pre = cur->Pre;
	cur->Pre->Next = cur->Next;
	free(cur);
	cur = NULL;
}
void DListRemoveAll(Node* p, DataType data)
{
	assert(p);
	Node* pos = p->Next;
	while (pos != p)
	{
		if (pos->data == data)
		{
			Node* cur = pos;
			pos = pos->Next;

			cur->Next->Pre = cur->Pre;
			cur->Pre->Next = cur->Next;
			free(cur);
		}
		else
		{
			pos = pos->Next;
		}
	}
}
void ListDestory(Node** p)
{
	assert(p);
	Node* cur = *p;
	cur = cur->Next;
	while (cur != *p)
	{
		Node* pos = cur;
		cur = cur->Next;
		free(pos);
	}
	free(*p);
	*p = NULL;
}
双向循环链表是一种特殊的链表,它的最后一个节点的 next 指针指向第一个节点,第一个节点的 prev 指针指向最后一个节点,因此可以实现循环遍历。带头结点的双向循环链表是在双向循环链表的基础上增加了一个头结点,可以方便地进行插入、删除等操作。以下是带头结点的双向循环链表的常见操作: ```c++ // 双向循环链表节点结构体 template <typename T> struct Node { T data; Node<T>* prev; Node<T>* next; Node() : data(T()), prev(nullptr), next(nullptr) {} Node(T _data, Node<T>* _prev = nullptr, Node<T>* _next = nullptr) : data(_data), prev(_prev), next(_next) {} }; // 带头结点的双向循环链表类 template <typename T> class DoubleLinkedList { public: DoubleLinkedList() : head(new Node<T>()), size(0) { head->prev = head->next = head; } ~DoubleLinkedList() { clear(); delete head; } // 在 index 处插入元素 void insert(int index, const T& value) { if (index < 0 || index > size) { throw std::out_of_range("Index out of range."); } Node<T>* cur = head; for (int i = 0; i < index; ++i) { cur = cur->next; } Node<T>* node = new Node<T>(value, cur, cur->next); cur->next->prev = node; cur->next = node; ++size; } // 删除 index 处的元素 void remove(int index) { if (index < 0 || index >= size) { throw std::out_of_range("Index out of range."); } Node<T>* cur = head->next; for (int i = 0; i < index; ++i) { cur = cur->next; } cur->prev->next = cur->next; cur->next->prev = cur->prev; delete cur; --size; } // 清空链表 void clear() { while (size > 0) { remove(0); } } // 获取第 index 个元素 T& get(int index) const { if (index < 0 || index >= size) { throw std::out_of_range("Index out of range."); } Node<T>* cur = head->next; for (int i = 0; i < index; ++i) { cur = cur->next; } return cur->data; } // 获取链表长度 int getSize() const { return size; } // 判断链表是否为空 bool isEmpty() const { return size == 0; } private: Node<T>* head; // 头结点 int size; // 链表长度 }; ``` 以上是带头结点的双向循环链表的常见操作,可以根据实际需求进行调整和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值