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;
}
相关推荐
南境十里·墨染春水6 小时前
C++传记(面向对象)虚析构函数 纯虚函数 抽象类 final、override关键字
开发语言·c++·笔记·算法
无巧不成书02186 小时前
30分钟入门Java:从历史到Hello World的小白指南
java·开发语言
2301_797172756 小时前
基于C++的游戏引擎开发
开发语言·c++·算法
比昨天多敲两行7 小时前
C++ 二叉搜索树
开发语言·c++·算法
Season4507 小时前
C++11之正则表达式使用指南--[正则表达式介绍]|[regex的常用函数等介绍]
c++·算法·正则表达式
问好眼8 小时前
《算法竞赛进阶指南》0x04 二分-1.最佳牛围栏
数据结构·c++·算法·二分·信息学奥赛
Birdy_x8 小时前
接口自动化项目实战(1):requests请求封装
开发语言·前端·python
海海不瞌睡(捏捏王子)8 小时前
C++ 知识点概要
开发语言·c++
桌面运维家9 小时前
VLAN配置进阶:抑制广播风暴,提升网络效率
开发语言·网络·php
一轮弯弯的明月9 小时前
Python基础-速通秘籍(下)
开发语言·笔记·python·学习