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;
}