目录
list是个双向链表 先定义一个双向链表
template<typename T>
struct Node
{
T data;
Node* prev;
Node* next;
Node(const T& d = T{},Node* prev = nullptr,Node* next = nullptr)
: data(d), prev(prev), next(next) {}
};
封装一个容器类
里面存储链表的头尾指针,然后写一些常用的函数
template<typename T>
class List
{
public:
List() :head(nullptr), tail(nullptr) {}
~List();//类外定义,销毁链表
void print()const;//正序输出
void rprint()const;//倒序输出
void push_back(const T& val);//尾插
void push_front(const T& val);//头插
void pop_back();//尾删
void pop_front();//头删
void remove(const T& val);//指定值删除
Node<T>* begin();//返回头指针
Node<T>* end();//返回尾指针
private:
Node<T>* head;
Node<T>* tail;
};
正序遍历
template<typename T>
void List<T>::print()const
{
if (head == nullptr)
{
cout << "链表为空" << endl;
return;
}
cout << "head -> ";
Node<T>* current = head;
while (current)
{
cout << current->data << " -> ";
current = current->next;
}
cout << "tail" << endl;
}
逆序遍历
template<typename T>
void List<T>::rprint()const
{
if (head == nullptr)
{
cout << "链表为空" << endl;
return;
}
cout << "tail -> ";
Node<T>* current = tail;
while (current)
{
cout << current->data << " -> ";
current = current->prev;
}
cout << "head" << endl;
}
尾插
template<typename T>
void List<T>::push_back(const T& val)
{
if (tail == nullptr)
{
head = new Node<T>(val);
tail = head;
return;
}
tail->next = new Node<T>(val,tail);
tail = tail->next;
}
头插
template<typename T>
void List<T>::push_front(const T& val)
{
if (tail == nullptr)
{
head = new Node<T>(val);
tail = head;
return;
}
head = new Node<T>(val,nullptr,head);
head->next->prev = head;
}
尾删
template<typename T>
void List<T>::pop_back()
{
if (tail == nullptr)
{
return;
}
Node<T>* dest = tail;
tail = tail->prev;
tail->next = nullptr;
delete dest;
}
头删
template<typename T>
void List<T>::pop_front()
{
if (tail == nullptr)
{
return;
}
Node<T>* dest = head;
head = head->next;
head->prev = nullptr;
delete dest;
}
按指定值删除
因为是仿写list容器,list容器的remove函数会把所有和指定目标相等的数据全部删除,所以我这个函数也是全部删除
template<typename T>
void List<T>::remove(const T& val)
{
if (head == nullptr)
{
cout << "链表为空" << endl;
return;
}
Node<T>* current = head;
while (current)
{
if (current->data == val)//找到
{
Node<T>* temp = current;//记录被删除节点
current->prev->next = current->next;//前节点指向后节点
current->next->prev = current->prev;//后节点指向前节点
current = temp->next;//指针移位
delete temp;
continue;
}
current = current->next;
}
}
返回首尾指针
类似返回首尾迭代器的功能
//返回头指针
template<typename T>
Node<T>* List<T>::begin()
{
return head;
}
//返回尾指针
template<typename T>
Node<T>* List<T>::end()
{
return tail;
}
最后删除所有元素,我这里写到析构函数里面了,也可以拿出来单独封装一个函数
template<typename T>
List<T>::~List()
{
if (tail == nullptr)
return;
Node<T>* dest;
while (head)
{
dest = head;
head = head->next;
delete dest;
}
cout << "链表已销毁" << endl;
}
一个简单的测试案例
测试代码的功能完整性
int main()
{
List<int>v;
v.push_back(3);
v.push_back(3);
v.push_back(3);
v.push_back(3);
v.push_back(4);
v.push_back(5);
v.push_front(2);
v.push_front(1);
v.remove(3);
v.print();
v.rprint();
v.pop_back();
v.pop_front();
v.print();
v.rprint();
cout <<v.begin()->data << endl;
cout <<v.end()->data << endl;
}
可以看到,没有任何问题。