C++(list)
目录
主要的成员函数:
元素访问:
容量查询:
插入删除操作:
示例:
头插:
尾插:
一个简单的list实现:
list是C++标准模板库(STL)中的双向链表容器,其头文件是<list>。list。不支持随机访问元素,所以访问元素的时间复杂度为O(n),但是list插入和删除的时间复杂度为O(1)。
list中一个节点包含数据域、前驱指针域和后继指针域。
如果想要访问中间某个节点,只能开头开始进行遍历。但是插入删除的话,不需要对数据进行移动,只需要改变链表中的指针域的指向就行。
主要的成员函数:
元素访问:
front():访问链表的第一个元素。
back():访问链表最后一个元素。
容量查询:
empty():判断链表是否为空,如果为空则返回为true,反之则为false。
size():判断链表中的节点个数。
插入删除操作:
push_back():在链表最后一个位置插入节点。
pop_back():将链表最后一个位置的节点删除。
push_front():在链表第一个位置插入节点。
pop_front():将链表第一个位置的节点删除。
insert():通过迭代器在指定位置插入节点。
erase():通过迭代器指定的位置删除节点。
clear():将链表进行清除。
示例:
#include <iostream>
#include <list>int main() {std::list<int> l;std::list<int> newl;for (int i = 0; i < 10; i++) {l.push_back(i);newl.push_front(i);}std::cout << "链表l的节点数值:" << std::endl;for (auto it = l.begin(); it != l.end(); ++it) {std::cout << *it << " ";}std::cout << std::endl;std::cout << "链表newl的节点数值:" << std::endl;for (auto it = newl.begin(); it != newl.end(); ++it) {std::cout << *it << " ";}return 0;
}
运行结果:
分别使用push_back()和push_front()进行插入节点,从运行结果可以知道,同样的插入顺序,但是在链表中的节点位置是相反的。因为push_front()是在链表头部进行插入,而push_back()是在链表尾部进行插入。
头插:
链表newl进行使用push_front()进行插入节点时,每次都是在head之后进行插入,所以当按照顺序插入0~9时,在链表中的节点顺序为9~0。
尾插:
链表l进行使用push_back()进行插入节点时,每次都是在tail之前进行插入,所以按照顺序插入0~9时,在链表中的节点顺序为0~9。
同理pop_front()和pop_back()函数也是同理,分别在head之后和tail之前的节点进行删除。
#include <iostream>
#include <list>int main() {std::list<int> l;std::list<int> newl;auto l_it = l.begin();auto newl_it = newl.begin();std::cout << "配合迭代器使用inset()和erase()进行插入和删除:" << std::endl;for (int i = 0; i < 10; i++) {l.insert(l_it, i);newl_it=newl.insert(newl_it, i);}std::cout << "链表l的节点数值:" << std::endl;for (auto it = l.begin(); it != l.end(); ++it) {std::cout << *it << " ";}std::cout << std::endl;std::cout << "链表newl的节点数值:" << std::endl;for (auto it = newl.begin(); it != newl.end(); ++it) {std::cout << *it << " ";}for (auto it = l.begin(); it != l.end();) {it=l.erase(it);}for (auto it = newl.begin(); it != newl.end();) {it = newl.erase(it);}std::cout << std::endl;std::cout << "链表l的节点个数:" << l.size() << std::endl;std::cout << "链表newl的节点个数:" << newl.size() << std::endl;return 0;
}
运行结果:
insert()操作不会指向插入位置的使迭代器失效,新插入的节点会被插入到指定迭代器位置的前面,insert()会返回指向新插入元素的迭代器。
erase()操作会导致只想删除元素的迭代器失效,erase()返回值为被删除元素的下一个元素的迭代器。
#include <iostream>
#include <list>int main() {std::list<int> l;std::list<int> newl;auto l_it = l.begin();auto newl_it = newl.end();std::cout << "配合迭代器使用inset()和erase()进行插入和删除:" << std::endl;for (int i = 0; i < 10; i++) {l.insert(l_it, i);newl.insert(newl_it, i);}std::cout << "链表l的节点数值:" << std::endl;for (auto it = l.begin(); it != l.end(); ++it) {std::cout << *it << " ";}std::cout << std::endl;std::cout << "链表newl的节点数值:" << std::endl;for (auto it = newl.begin(); it != newl.end(); ++it) {std::cout << *it << " ";}newl.clear();std::cout << std::endl;std::cout << "链表l的节点个数:" << l.size() << std::endl;std::cout << "链表newl的节点个数:" << newl.size() << std::endl;return 0;
}
运行结果:
一个简单的list实现:
#include <iostream>
#include <list>
#include <memory>template<typename T>
struct Node {T _data;Node* next;Node* prev;Node():_data(0),next(nullptr),prev(nullptr){}Node(const T& data):_data(data),next(nullptr),prev(nullptr){}
};template<typename T>
class List {
public:List():_size(0) {head = new Node<T>();tail = new Node<T>();head->next = tail;tail->prev = head;}~List() {clear();delete head;delete tail;}void clear() {Node<T>* temp = head->next;while (temp != tail) {Node<T>* newtemp = temp;temp = temp->next;delete newtemp;}head->next = tail;tail->prev = head;}void push_front(const T& value) {Node<T>* newnode = new Node<T>(value);newnode->next = head->next;head->next->prev = newnode;head->next = newnode;newnode->prev = head;_size++;}void push_back(const T& value) {Node<T>* newnode = new Node<T>(value);newnode->prev = tail->prev;tail->prev->next = newnode;newnode->next = tail;tail->prev = newnode;_size++;}void pop_front() {if (!empty()) {head->next = head->next->next;head->next->prev = head;_size--;}}void pop_back() {if (!empty()) {tail->prev=tail->prev->prev;tail->prev->next=tail;_size--;}}size_t size()const {return _size;}bool empty()const {return head->next == tail;}Node<T>* begin()const {return head->next;}Node<T>* end()const {return tail;}
private:Node<T>* head;Node<T>* tail;size_t _size;
};
int main() {List<int> l;List<int> newl;std::cout << "l中的节点个数:" << l.size() << std::endl;std::cout << "newl中的节点个数:" << newl.size() << std::endl;for (int i = 0; i < 10; i++) {l.push_front(i);newl.push_back(i);}std::cout << "l中的节点个数:" << l.size() << std::endl;std::cout << "newl中的节点个数:" << newl.size() << std::endl;auto l_ptr = l.begin();while (l_ptr != l.end()) {std::cout << l_ptr->_data << " ";l_ptr = l_ptr->next;}std::cout << std::endl;auto newl_ptr = newl.begin();while (newl_ptr != newl.end()) {std::cout << newl_ptr->_data << " ";newl_ptr = newl_ptr->next;}return 0;
}
运行结果: