C++ 双向循环链表

c++中双向循环链表的第一部分是数据域,用于存储具体的数据信息,这个数据可以是任何类型,取决于具体的应用场景。第二部分是指向前驱节点的指针prev,第三部分是指向后继节点的指针next,同样和prev一样是一个引用或指针。

双向循环链表:头插法,先创建一个节点,将节点的prev指向虚拟头结点,将节点的next指向虚拟头结点的下一个节点,最后将对应节点的指针指向对应位置。

尾插法,先创建一个节点,将节点的prev指向虚拟头结点的prev所指向的指针,将节点的next指针指向虚拟头结点,最后将对应节点的指针指向对应位置。

任意插,找到需要插入的指针后,新节点的prev指向插入节点位置的节点,新节点next指向插入节点位置的下一个节点,最后将节点的指针分别指向对应位置。

节点删除,将节点的前一个节点的next指针指向后一个节点,将后一个节点的prev指向节点前一个节点。并且释放节点的内存。注意,删除的节点不能是虚拟头结点。

代码见下:

cpp 复制代码
#include<iostream>
using namespace std;

//双向循环链表
template<typename T>
struct Node {
	T data;
	Node* prev;
	Node* next;
	Node(const T& value) :data(value), prev(NULL), next(NULL) {

	}
};

template<class T>
class DoublyLinkedList {
public:
	DoublyLinkedList();
	~DoublyLinkedList();

	void push_front(const T& value);
	void push_back(const T& value);
	void insert_after(Node<T>* node, const T& value);
	void delete_node(Node<T>* node);
	void modify(Node<T>* node, const T& value);
	Node<T>* find(const T& value) const;

	void print() const;
	int size() const;
	bool empty() const;

private:
	Node<T>* m_dummyHead;
	int m_size;
};

template<class T>
DoublyLinkedList<T>::DoublyLinkedList(): m_size(0)
{
	m_dummyHead = new Node<T>(T());
	m_dummyHead->prev = m_dummyHead;
	m_dummyHead->next = m_dummyHead;
}

template<class T>
DoublyLinkedList<T>::~DoublyLinkedList()
{
	while (m_size > 0) {
		delete_node(m_dummyHead->next);
	}
	delete m_dummyHead;
	m_dummyHead = NULL;
}

template<class T>
void DoublyLinkedList<T>::push_front(const T& value)
{
	Node<T>* newNode = new Node<T>(value);
	newNode->prev = m_dummyHead;
	newNode->next = m_dummyHead->next;

	m_dummyHead->next->prev = newNode;
	m_dummyHead->next = newNode;
	++m_size;
}

template<class T>
void DoublyLinkedList<T>::push_back(const T& value)
{
	Node<T>* newNode = new Node<T>(value);

	newNode->prev = m_dummyHead->prev;
	newNode->next = m_dummyHead;

	m_dummyHead->prev->next = newNode;
	m_dummyHead->prev = newNode;
	++m_size;
}

template<class T>
void DoublyLinkedList<T>::insert_after(Node<T>* node, const T& value)
{
	if (node == NULL || node == m_dummyHead) {
		return;
	}
	Node<T>* newNode = new Node<T>(value);

	newNode->prev = node;
	newNode->next = node->next;

	node->next->prev = newNode;
	node->next = newNode;
	++m_size;
}

template<class T>
void DoublyLinkedList<T>::delete_node(Node<T>* node)
{
	if (node == NULL || node == m_dummyHead) {
		return;
	}
	node->prev->next = node->next;
	node->next->prev = node->prev;
	delete node;
	--m_size;
}

template<class T>
void DoublyLinkedList<T>::modify(Node<T>* node, const T& value)
{
	if (node == NULL || node == m_dummyHead) {
		return;
	}
	node->data = value;
}

template<class T>
Node<T>* DoublyLinkedList<T>::find(const T& value) const
{
	Node<T>* curr = m_dummyHead->next;
	while (curr != m_dummyHead) {
		if (curr->data == value) {
			return curr;
		}
		curr = curr->next;
	}
	return NULL;
}

template<class T>
void DoublyLinkedList<T>::print() const
{
	Node<T>* curr = m_dummyHead->next;
	while (curr != m_dummyHead) {
		cout << curr->data << " ";
		curr = curr->next;
	}
	cout << endl;
}

template<class T>
int DoublyLinkedList<T>::size() const
{
	return m_size;
}

template<class T>
bool DoublyLinkedList<T>::empty() const
{
	return m_size == 0;
}









int main() {
	DoublyLinkedList<char> dll;
	dll.push_back('i'); dll.print();
	dll.push_back('c'); dll.print();
	dll.push_back('p'); dll.print();
	dll.push_back('c'); dll.print();

	dll.push_front('m'); dll.print();
	dll.push_front('a'); dll.print();

	Node<char>* nd = dll.find('a');
	dll.insert_after(nd, 'c'); dll.print();
	nd = dll.find('m');
	dll.insert_after(nd, '/'); dll.print();

	nd = dll.find('i');
	dll.modify(nd, 'c'); dll.print();

	nd = dll.find('m');
	dll.delete_node(nd); dll.print();

	cout << dll.empty() << endl;
	cout << dll.size() << endl;

	return 0;
}

代码练习1 对应蓝桥云课 小王子双链表 代码见下

cpp 复制代码
#include<iostream>
using namespace std;

//双向循环链表
template<typename T>
struct Node {
	T data;
	Node* prev;
	Node* next;
	Node(const T& value) :data(value), prev(NULL), next(NULL) {

	}
};

template<class T>
class DoublyLinkedList {
public:
	DoublyLinkedList();
	~DoublyLinkedList();

	void push_front(const T& value);
	void push_back(const T& value);
	void insert_after(Node<T>* node, const T& value);
	void delete_node(Node<T>* node);
	void modify(Node<T>* node, const T& value);
	Node<T>* find(const T& value) const;

	void print() const;
	int size() const;
	bool empty() const;

private:
	Node<T>* m_dummyHead;
	int m_size;
};

template<class T>
DoublyLinkedList<T>::DoublyLinkedList(): m_size(0)
{
	m_dummyHead = new Node<T>(T());
	m_dummyHead->prev = m_dummyHead;
	m_dummyHead->next = m_dummyHead;
}

template<class T>
DoublyLinkedList<T>::~DoublyLinkedList()
{
	while (m_size > 0) {
		delete_node(m_dummyHead->next);
	}
	delete m_dummyHead;
	m_dummyHead = NULL;
}

template<class T>
void DoublyLinkedList<T>::push_front(const T& value)
{
	Node<T>* newNode = new Node<T>(value);
	newNode->prev = m_dummyHead;
	newNode->next = m_dummyHead->next;

	m_dummyHead->next->prev = newNode;
	m_dummyHead->next = newNode;
	++m_size;
}

template<class T>
void DoublyLinkedList<T>::push_back(const T& value)
{
	Node<T>* newNode = new Node<T>(value);

	newNode->prev = m_dummyHead->prev;
	newNode->next = m_dummyHead;

	m_dummyHead->prev->next = newNode;
	m_dummyHead->prev = newNode;
	++m_size;
}

template<class T>
void DoublyLinkedList<T>::insert_after(Node<T>* node, const T& value)
{
	if (node == NULL || node == m_dummyHead) {
		return;
	}
	Node<T>* newNode = new Node<T>(value);

	newNode->prev = node;
	newNode->next = node->next;

	node->next->prev = newNode;
	node->next = newNode;
	++m_size;
}

template<class T>
void DoublyLinkedList<T>::delete_node(Node<T>* node)
{
	if (node == NULL || node == m_dummyHead) {
		return;
	}
	node->prev->next = node->next;
	node->next->prev = node->prev;
	delete node;
	--m_size;
}

template<class T>
void DoublyLinkedList<T>::modify(Node<T>* node, const T& value)
{
	if (node == NULL || node == m_dummyHead) {
		return;
	}
	node->data = value;
}

template<class T>
Node<T>* DoublyLinkedList<T>::find(const T& value) const
{
	Node<T>* curr = m_dummyHead->next;
	while (curr != m_dummyHead) {
		if (curr->data == value) {
			return curr;
		}
		curr = curr->next;
	}
	return NULL;
}

template<class T>
void DoublyLinkedList<T>::print() const
{
	Node<T>* curr = m_dummyHead->next;
	while (curr != m_dummyHead) {
		cout << curr->data << " ";
		curr = curr->next;
	}
	cout << endl;
}

template<class T>
int DoublyLinkedList<T>::size() const
{
	return m_size;
}

template<class T>
bool DoublyLinkedList<T>::empty() const
{
	return m_size == 0;
}


int main() {
	DoublyLinkedList<int> dll;
	for (int i = 1; i <= 10; ++i) {
		dll.push_back(i);
	}
	int n;
	cin >> n;
	while (n--) {
		int x;
		cin >> x;
		Node<int>* nd = dll.find(x);
		dll.delete_node(nd);
		dll.push_front(x);
		dll.print();
	}

	return 0;
}
相关推荐
Boilermaker19926 小时前
[Java 并发编程] Synchronized 锁升级
java·开发语言
MM_MS6 小时前
Halcon变量控制类型、数据类型转换、字符串格式化、元组操作
开发语言·人工智能·深度学习·算法·目标检测·计算机视觉·视觉检测
꧁Q༒ོγ꧂7 小时前
LaTeX 语法入门指南
开发语言·latex
njsgcs7 小时前
ue python二次开发启动教程+ 导入fbx到指定文件夹
开发语言·python·unreal engine·ue
alonewolf_997 小时前
JDK17新特性全面解析:从语法革新到模块化革命
java·开发语言·jvm·jdk
古城小栈7 小时前
Rust 迭代器产出的引用层数——分水岭
开发语言·rust
ghie90907 小时前
基于MATLAB的TLBO算法优化实现与改进
开发语言·算法·matlab
恋爱绝缘体17 小时前
2020重学C++重构你的C++知识体系
java·开发语言·c++·算法·junit
wuk9987 小时前
VSC优化算法MATLAB实现
开发语言·算法·matlab
AI小怪兽8 小时前
基于YOLOv13的汽车零件分割系统(Python源码+数据集+Pyside6界面)
开发语言·python·yolo·无人机