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;
}
相关推荐
luj_17688 分钟前
大航海时代:沉浸式财商实战沙盒
c语言·开发语言·网络·经验分享·算法
赵广陆39 分钟前
企业实战:Markdown图片检索
android·java·开发语言
C++、Java和Python的菜鸟40 分钟前
第3章 从0开始用若依
java·开发语言
LuminousCPP1 小时前
数据结构基础篇(二):顺序表与链表全方位对比|从内存布局到 CPU 缓存理解底层差异
c语言·数据结构·经验分享·链表·缓存
夜雪一千1 小时前
Python 如何实现 SHA 加密?SHA1 / SHA256 / SHA512 实战教程
开发语言·python
王老师青少年编程1 小时前
2021年CSP-J初赛真题及答案解析(完善程序2)
c++·真题·csp-j·答案·csp·初赛·信奥赛
有点。1 小时前
C++二叉树(一)
开发语言·数据结构·c++
民乐团扒谱机2 小时前
【微实验】谐波乘积谱(HPS)算法深度解析:原理、数学与代码实现
开发语言·人工智能·python·算法·语音识别·音乐
报错小能手2 小时前
Go 语言结构 基础语法
开发语言·后端·golang
Lazionr2 小时前
stack与queue:底层实现与容器适配器
开发语言·数据结构·c++