C++实现单链表
1.节点类
template <class T>
class Node
{
public:
T data;
Node<T> *next;
Node(T data);
};
2.链表类
template <class T>
class LinkedList
{
public:
// 初始化单节点链表(工厂方法)
static LinkedList<T> *initSingletonList(T data);
// 构造函数
LinkedList();
// 析构函数
~LinkedList();
// 核心操作
void insertAtHead(T data);
void insertAtTail(T data);
void insertAtPosition(T data, int position);
bool remove(T data);
bool removeAtPosition(int position);
// 查询操作
bool contains(T data) const;
int getPosition(T data) const;
T getAtPosition(int position) const;
// 工具方法
bool isEmpty() const;
int getSize() const;
void clear();
void reverse();
void print() const;
void printReverse() const;
LinkedList<T> *clone() const;
// 重载操作符
bool operator==(const LinkedList<T> &other) const;
// 链表状态
Node<T> *head;
int size;
private:
// 递归打印辅助函数
void printReverseHelper(Node<T> *current) const;
// 递归反转辅助函数
void reverseHelper(Node<T> *prev, Node<T> *current);
};
3.具体实现
// 直接在头文件中实现模板类
template <class T>
Node<T>::Node(T data) : data(data), next(nullptr) {}
// 构造函数
template <class T>
LinkedList<T>::LinkedList() : head(nullptr), size(0) {}
// 析构函数
template <class T>
LinkedList<T>::~LinkedList() { clear(); }
template <class T>
// 初始化单节点链表(工厂方法)
LinkedList<T> *LinkedList<T>::initSingletonList(T data)
{
LinkedList<T> *list = new LinkedList<T>();
list->insertAtHead(data);
return list;
}
// 核心操作
template <class T>
void LinkedList<T>::insertAtHead(T data)
{
Node<T> *newNode = new Node<T>(data);
newNode->next = head;
head = newNode;
size++;
}
template <class T>
void LinkedList<T>::insertAtTail(T data)
{
Node<T> *newNode = new Node<T>(data);
if (head == nullptr)
{
head = newNode;
}
else
{
Node<T> *current = head;
while (current->next != nullptr)
{
current = current->next;
}
current->next = newNode;
}
size++;
}
template <class T>
void LinkedList<T>::insertAtPosition(T data, int position)
{
if (position < 0 || position > size)
{
std::cerr << "invaild position: " << position << std::endl;
return;
}
if (position == 0)
{
insertAtHead(data);
return;
}
if (position == size)
{
insertAtTail(data);
return;
}
Node<T> *newNode = new Node<T>(data);
Node<T> *current = head;
for (int i = 0; i < position - 1; i++)
{
current = current->next;
}
newNode->next = current->next;
current->next = newNode;
size++;
}
template <class T>
bool LinkedList<T>::remove(T data)
{
if (head == nullptr)
return false;
// 处理头节点
if (head->data == data)
{
Node<T> *toDel = head;
head = head->next;
delete toDel;
size--;
return true;
}
Node<T> *current = head;
while (current->next != nullptr)
{
if (current->next->data == data)
{
Node<T> *toDel = current->next;
current->next = current->next->next;
delete toDel;
size--;
return true;
}
current = current->next;
}
return false;
}
template <class T>
bool LinkedList<T>::removeAtPosition(int position)
{
if (position < 0 || position >= size)
{
std::cerr << "Invalid position: " << position << std::endl;
return false;
}
if (position == 0)
{
Node<T> *toDelete = head;
head = head->next;
delete toDelete;
size--;
return true;
}
Node<T> *current = head;
for (int i = 0; i < position - 1; i++)
{
current = current->next;
}
Node<T> *toDelete = current->next;
current->next = current->next->next;
delete toDelete;
size--;
return true;
}
// 查询操作
template <class T>
bool LinkedList<T>::contains(T data) const
{
Node<T> *current = head;
while (current != nullptr)
{
if (current->data == data)
return true;
current = current->next;
}
return false;
}
template <class T>
int LinkedList<T>::getPosition(T data) const
{
Node<T> *current = head;
int index = 0;
while (current != nullptr)
{
if (current->data == data)
return index;
current = current->next;
index++;
}
return -1;
}
template <class T>
T LinkedList<T>::getAtPosition(int position) const
{
if (position < 0 || position >= size)
{
throw std::out_of_range("Position out of range");
}
Node<T> *current = head;
for (int i = 0; i < position; i++)
{
current = current->next;
}
return current->data;
}
// 工具方法
template <class T>
bool LinkedList<T>::isEmpty() const
{
return head == nullptr;
}
template <class T>
int LinkedList<T>::getSize() const
{
return size;
}
template <class T>
void LinkedList<T>::clear()
{
if (head == nullptr)
return;
Node<T> *current = head;
while (current != nullptr)
{
Node<T> *next = current->next;
delete current;
current = next;
}
head = nullptr;
size = 0;
}
template <class T>
void LinkedList<T>::reverse()
{
if (head == nullptr || head->next == nullptr)
return;
reverseHelper(nullptr, head);
}
template <class T>
void LinkedList<T>::print() const
{
Node<T> *current = head;
std::cout << "Head -> ";
while (current != nullptr)
{
std::cout << current->data;
if (current->next != nullptr)
{
std::cout << " -> ";
}
current = current->next;
}
std::cout << " -> nullptr" << std::endl;
}
template <class T>
void LinkedList<T>::printReverse() const
{
std::cout << "Reversed: nullptr <- ";
printReverseHelper(head);
std::cout << "Head" << std::endl;
}
template <class T>
LinkedList<T> *LinkedList<T>::clone() const
{
LinkedList<T> *newList = new LinkedList<T>();
if (head == nullptr)
return newList;
Node<T> *current = head;
Node<T> *tail = nullptr;
while (current != nullptr)
{
Node<T> *newNode = new Node<T>(current->data);
if (newList->head == nullptr)
{
newList->head = newNode;
tail = newNode;
}
else
{
tail->next = newNode;
tail = newNode;
}
newList->size++;
current = current->next;
}
return newList;
}
// 重载操作符
template <class T>
bool LinkedList<T>::operator==(const LinkedList<T> &other) const
{
if (size != other.size)
return false;
Node<T> *current1 = head;
Node<T> *current2 = other.head;
while (current1 != nullptr && current2 != nullptr)
{
if (current1->data != current2->data)
{
return false;
}
current1 = current1->next;
current2 = current2->next;
}
return true;
}
// 递归打印辅助函数
template <class T>
void LinkedList<T>::printReverseHelper(Node<T> *current) const
{
if (current == nullptr)
return;
printReverseHelper(current->next);
std::cout << current->data;
if (current != head)
{
std::cout << " <- ";
}
}
// 递归反转辅助函数
template <class T>
void LinkedList<T>::reverseHelper(Node<T> *prev, Node<T> *current)
{
if (current == nullptr)
{
head = prev;
return;
}
Node<T> *next = current->next;
current->next = prev;
reverseHelper(current, next);
}