数据结构 C++双向链表
双向链表
节点类型
template <typename T>
class Node
{
public:
Node(T data) : _data(data), prev(nullptr), next(nullptr) {}
public:
T _data;
Node *prev;
Node *next;
};
定义类
template <typename T>
class DoublyLinkedList
{
public:
DoublyLinkedList() : head(nullptr), tail(nullptr), length(0) {}
~DoublyLinkedList()
{
Clear();
}
DoublyLinkedList(const &) = delete;
operator=(const &) = delete;
void insertAtHead(T data); // 在头部插入节点
void insertAtTail(T data); // 在尾部插入节点
void insertPosNode(int pos, T data); // 在指定位置插入
void deleteAtHead(); // 删除头部节点
void deleteAtTail(); // 删除尾部节点
void deleteAtPosNode(int pos); // 删除指定位置节点
int getSize();
bool isEmpty();
void Clear();
void printForward() const;
void printBackWard() const;
public:
Node<T> *head;
Node<T> *tail;
int length;
};
1.在头部插入
template <typename T>
void DoublyLinkedList<T>::insertAtHead(T data)
{
Node<T> *newNode = new Node<T>(data);
if (head == nullptr)
{
head = tail = newNode;
}
else
{
newNode->next = head;
head->prev = newNode;
head = newNode;
}
length++;
}
2.在尾部插入
template <typename T>
void DoublyLinkedList<T>::insertAtTail(T data)
{
Node<T> *newNode = new Node<T>(data);
if (tail == nullptr)
{
head = tail = newNode;
}
else
{
tail->next = newNode;
newNode->prev = tail;
tail = newNode;
}
length++;
}
3.在指定位置插入
// 在指定位置插入
template <typename T>
inline void DoublyLinkedList<T>::insertPosNode(int pos, T data)
{
if (pos < 0 || pos > length)
{
std::cout << "invaild postion" << std::endl;
return;
}
if (pos == 0)
{
insertAtHead(data);
return;
}
if (pos == length)
{
insertAtTail(data);
return;
}
Node<T> *current = head;
for (int i = 0; i < pos - 1; i++)
{
current = current->next;
}
Node<T> *newNode = new Node<T>(data);
newNode->next = current->next;
newNode->prev = current;
current->next->prev = newNode;
current->next = newNode;
length++;
}
4.头节点删除
// 删除头部节点
template <typename T>
inline void DoublyLinkedList<T>::deleteAtHead()
{
if (head == nullptr)
return;
Node<T> *temp = head;
if (head == tail)
{
head = tail = nullptr;
}
else
{
head = head->next;
head->prev = nullptr;
}
delete temp;
length--;
}
5.尾节点删除
// 删除尾部节点
template <typename T>
inline void DoublyLinkedList<T>::deleteAtTail()
{
if (tail == nullptr)
return;
Node<T> *temp = tail;
if (tail == head)
{
tail = head = nullptr;
}
else
{
tail = tail->prev;
tail->next = nullptr;
}
delete temp;
length--;
}
6.在指定位置删除
// 删除指定位置节点
template <typename T>
inline void DoublyLinkedList<T>::deleteAtPosNode(int pos)
{
if (pos < 0 || pos >= length)
{
std::cout << "invaild pos" << std::endl;
return;
}
if (pos == 0)
{
deleteAtHead();
return;
}
if (pos == length - 1)
{
deleteAtTail();
return;
}
Node<T> *current = head;
for (int i = 0; i < pos; ++i)
{
current = current->next;
}
current->prev->next = current->next;
current->next->prev = current->prev;
delete current;
length--;
}
7.清除链表
// 清除链表
template <typename T>
inline void DoublyLinkedList<T>::Clear()
{
while (head != nullptr)
{
Node<T> *temp = head;
head = head->next;
delete temp;
}
tail = nullptr;
length = 0;
}
完整代码
#ifndef DoublyLinkedList_H
#define DoublyLinkedList_H
#include <iostream>
template <typename T>
class Node
{
public:
Node(T data) : _data(data), prev(nullptr), next(nullptr) {}
public:
T _data;
Node *prev;
Node *next;
};
template <typename T>
class DoublyLinkedList
{
public:
DoublyLinkedList() : head(nullptr), tail(nullptr), length(0) {}
~DoublyLinkedList()
{
Clear();
}
DoublyLinkedList(const &) = delete;
operator=(const &) = delete;
void insertAtHead(T data); // 在头部插入节点
void insertAtTail(T data); // 在尾部插入节点
void insertPosNode(int pos, T data); // 在指定位置插入
void deleteAtHead(); // 删除头部节点
void deleteAtTail(); // 删除尾部节点
void deleteAtPosNode(int pos); // 删除指定位置节点
int getSize();
bool isEmpty();
void Clear();
void printForward() const;
void printBackWard() const;
public:
Node<T> *head;
Node<T> *tail;
int length;
};
// 在头部插入
template <typename T>
void DoublyLinkedList<T>::insertAtHead(T data)
{
Node<T> *newNode = new Node<T>(data);
if (head == nullptr)
{
head = tail = newNode;
}
else
{
newNode->next = head;
head->prev = newNode;
head = newNode;
}
length++;
}
// 在尾部插入
template <typename T>
void DoublyLinkedList<T>::insertAtTail(T data)
{
Node<T> *newNode = new Node<T>(data);
if (tail == nullptr)
{
head = tail = newNode;
}
else
{
tail->next = newNode;
newNode->prev = tail;
tail = newNode;
}
length++;
}
// 在指定位置插入
template <typename T>
inline void DoublyLinkedList<T>::insertPosNode(int pos, T data)
{
if (pos < 0 || pos > length)
{
std::cout << "invaild postion" << std::endl;
return;
}
if (pos == 0)
{
insertAtHead(data);
return;
}
if (pos == length)
{
insertAtTail(data);
return;
}
Node<T> *current = head;
for (int i = 0; i < pos - 1; i++)
{
current = current->next;
}
Node<T> *newNode = new Node<T>(data);
newNode->next = current->next;
newNode->prev = current;
current->next->prev = newNode;
current->next = newNode;
length++;
}
// 删除头部节点
template <typename T>
inline void DoublyLinkedList<T>::deleteAtHead()
{
if (head == nullptr)
return;
Node<T> *temp = head;
if (head == tail)
{
head = tail = nullptr;
}
else
{
head = head->next;
head->prev = nullptr;
}
delete temp;
length--;
}
// 删除尾部节点
template <typename T>
inline void DoublyLinkedList<T>::deleteAtTail()
{
if (tail == nullptr)
return;
Node<T> *temp = tail;
if (tail == head)
{
tail = head = nullptr;
}
else
{
tail = tail->prev;
tail->next = nullptr;
}
delete temp;
length--;
}
// 删除指定位置节点
template <typename T>
inline void DoublyLinkedList<T>::deleteAtPosNode(int pos)
{
if (pos < 0 || pos >= length)
{
std::cout << "invaild pos" << std::endl;
return;
}
if (pos == 0)
{
deleteAtHead();
return;
}
if (pos == length - 1)
{
deleteAtTail();
return;
}
Node<T> *current = head;
for (int i = 0; i < pos; ++i)
{
current = current->next;
}
current->prev->next = current->next;
current->next->prev = current->prev;
delete current;
length--;
}
// 获取链表大小
template <typename T>
inline int DoublyLinkedList<T>::getSize()
{
return length;
}
// 判断链表是否为空
template <typename T>
inline bool DoublyLinkedList<T>::isEmpty()
{
return length == 0;
}
// 清除链表
template <typename T>
inline void DoublyLinkedList<T>::Clear()
{
while (head != nullptr)
{
Node<T> *temp = head;
head = head->next;
delete temp;
}
tail = nullptr;
length = 0;
}
// 正向打印链表
template <typename T>
inline void DoublyLinkedList<T>::printForward() const
{
Node<T> *current = head;
std::cout << "head->";
while (current != nullptr)
{
std::cout << current->_data;
if (current->next)
std::cout << "->";
current = current->next;
}
std::cout << "->nullptr" << std::endl;
}
// 反向打印链表
template <typename T>
inline void DoublyLinkedList<T>::printBackWard() const
{
Node<T> *current = tail;
std::cout << "tail->";
while (current != nullptr)
{
std::cout << current->_data;
if (current->prev)
std::cout << "->";
current = current->prev;
}
std::cout << "->nullptr" << std::endl;
}
#endif
#include <iostream>
#include "DoublyLinkedList.hpp"
int main(int argc, char const *argv[])
{
DoublyLinkedList<int> list;
// 测试 insertAtHead
std::cout << "Insert at head: 3, 2, 1" << std::endl;
list.insertAtHead(3);
list.insertAtHead(2);
list.insertAtHead(1);
list.printForward(); // 期望输出: head->1->2->3->nullptr
list.printBackWard(); // 期望输出: tail->3->2->1->nullptr
// 测试 insertAtTail
std::cout << "\nInsert at tail: 4, 5" << std::endl;
list.insertAtTail(4);
list.insertAtTail(5);
list.printForward(); // head->1->2->3->4->5->nullptr
// 测试 insertPosNode
std::cout << "\nInsert at position 2: value 99" << std::endl;
list.insertPosNode(2, 99);
list.printForward(); // head->1->2->99->3->4->5->nullptr
// 测试 deleteAtHead
std::cout << "\nDelete at head" << std::endl;
list.deleteAtHead();
list.printForward(); // head->2->99->3->4->5->nullptr
// 测试 deleteAtTail
std::cout << "\nDelete at tail" << std::endl;
list.deleteAtTail();
list.printForward(); // head->2->99->3->4->nullptr
// 测试 deleteAtPosNode
std::cout << "\nDelete at position 1" << std::endl;
list.deleteAtPosNode(1);
list.printForward(); // head->2->3->4->nullptr
// 测试 getSize 和 isEmpty
std::cout << "\nSize: " << list.getSize() << std::endl; // 期望输出: 4
std::cout << "Is empty? " << (list.isEmpty() ? "Yes" : "No") << std::endl; // No
// 测试 Clear
std::cout << "\nClear list" << std::endl;
list.Clear();
std::cout << "Size after clear: " << list.getSize() << std::endl; // 0
std::cout << "Is empty now? " << (list.isEmpty() ? "Yes" : "No") << std::endl; // Yes
return 0;
}

浙公网安备 33010602011771号