c++ STL list 遍历删除节点



list遍历删除节点时,处理不好会出现崩溃的情况。

错误方法

下面这种用法会在for的地方崩溃,分析 第一次for循环的时候 it=0,当t.erase(it)执行完成之后 it就变成了 -17891602,表明it不能再作为迭代器进行运算,自然会报错。

void CExmp::removeelem(list<int> &li, int value)
{
    for (list<int>::iterator it = li.begin(); it != li.end();++it)
    {
        if (value == *it)
            li.erase(it);
    }
}

正确方法

void CExmp::removeelem(list<int> &li, int value)
{
    for (list<int>::iterator it = li.begin(); it != li.end();)
    {
        if (value == *it)
            li.erase(it++);
        else
            ++it;
    }
}
STL(Standard Template Library)是C++的一个标准库,其包含了许多常用的数据结构和算法。其list是一种常用的数据结构,它是一个双向链表,可以实现快速的插入和删除操作。 下面是C++STL list的简单实现: ```cpp template <typename T> class List { private: struct Node { T data; Node* prev; Node* next; Node(const T& d = T(), Node* p = nullptr, Node* n = nullptr) : data(d), prev(p), next(n) {} }; Node* head; Node* tail; int size; public: List() : head(nullptr), tail(nullptr), size(0) {} List(const List& other) : head(nullptr), tail(nullptr), size(0) { for (const auto& item : other) { push_back(item); } } ~List() { clear(); } List& operator=(const List& other) { if (this != &other) { List tmp(other); swap(tmp); } return *this; } void push_back(const T& item) { Node* new_node = new Node(item, tail, nullptr); if (tail) { tail->next = new_node; } else { head = new_node; } tail = new_node; ++size; } void push_front(const T& item) { Node* new_node = new Node(item, nullptr, head); if (head) { head->prev = new_node; } else { tail = new_node; } head = new_node; ++size; } void pop_back() { if (tail) { Node* tmp = tail; tail = tail->prev; if (tail) { tail->next = nullptr; } else { head = nullptr; } delete tmp; --size; } } void pop_front() { if (head) { Node* tmp = head; head = head->next; if (head) { head->prev = nullptr; } else { tail = nullptr; } delete tmp; --size; } } T& front() { return head->data; } T& back() { return tail->data; } bool empty() const { return size == 0; } int size() const { return size; } void clear() { while (!empty()) { pop_back(); } } class iterator { private: Node* ptr; public: iterator(Node* p = nullptr) : ptr(p) {} iterator(const iterator& other) : ptr(other.ptr) {} iterator& operator++() { ptr = ptr->next; return *this; } iterator operator++(int) { iterator tmp(*this); ptr = ptr->next; return tmp; } iterator& operator--() { ptr = ptr->prev; return *this; } iterator operator--(int) { iterator tmp(*this); ptr = ptr->prev; return tmp; } T& operator*() const { return ptr->data; } T* operator->() const { return &(ptr->data); } bool operator==(const iterator& other) const { return ptr == other.ptr; } bool operator!=(const iterator& other) const { return ptr != other.ptr; } }; iterator begin() const { return iterator(head); } iterator end() const { return iterator(nullptr); } iterator rbegin() const { return iterator(tail); } iterator rend() const { return iterator(nullptr); } void swap(List& other) { std::swap(head, other.head); std::swap(tail, other.tail); std::swap(size, other.size); } }; ``` 上述代码List定义了一个私有结构体Node,它表示双向链表的每个节点。Node包含了数据成员data、指向前一个节点的指针prev和指向后一个节点的指针next。List还包含了头指针head、尾指针tail和大小size等数据成员。 List类提供了许多操作,包括push_back、push_front、pop_back、pop_front、front、back、empty、size、clear等。其,push_back和push_front分别表示在双向链表的末尾和开头插入一个元素,pop_back和pop_front分别表示删除双向链表的末尾和开头的元素,front和back分别表示获取双向链表的第一个和最后一个元素,empty表示判断双向链表是否为空,size表示获取双向链表元素的个数,clear表示清空双向链表的所有元素。 List类还定义了一个迭代器iterator,它可以用于遍历双向链表的所有元素。迭代器包含了一个指向Node的指针ptr,它可以指向双向链表的任意一个节点。迭代器提供了许多操作,包括++、--、*、->、==、!=等。其,++和--分别表示迭代器向前和向后移动一个位置,*表示获取迭代器所指向节点的数据成员data,->表示获取迭代器所指向节点的数据成员data的指针,==和!=分别表示判断两个迭代器是否相等和不相等。 List还提供了一些其他操作,比如拷贝构造函数、析构函数、赋值运算符、begin、end、rbegin、rend和swap等。其,拷贝构造函数用于复制另一个List对象,析构函数用于释放所有节点的内存,赋值运算符用于将一个List对象赋值给另一个List对象,begin和end分别返回指向双向链表第一个元素和最后一个元素的迭代器,rbegin和rend分别返回指向双向链表最后一个元素和第一个元素的迭代器,swap用于交换两个List对象的所有数据成员。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

i胡说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值