list (understand and use)
what is list
In the C++ standard library, std::list
it is a doubly linked list container used to store a series of elements. Unlike containers such as and std::vector
, elements are organized using the data structure of a linked list, so it has unique advantages and performance characteristics in certain operations. The following is a detailed introduction to std::list:std::deque
std::list
Features and Benefits
Doubly linked list structure:
std::list
A doubly linked list is used internally to store elements. This means that inserting and deleting elements does not cause memory reallocation and copying of other elements, thus having constant time complexity on these operations.
Efficient insertion and deletion operations: Due to the linked list structure, the operation efficiency of inserting and deleting elements is very high. For heavy insertion and deletion operations, std::list tends to have an advantage over other containers.
Stability of iterators: Instd::list
, insertion and deletion of elements will not invalidate iterators, unless the deletion is exactly the element pointed by the iterator. This makes inserting and deleting operations more convenient and safe during traversal.
Space occupation:std::list
Each element needs to store a pointer to the preceding and following elements, so compared to an array-type container,std::list
the space occupation will be higher.
basic operation
push_back()
Andpush_front()
: Inserts elements at the end and beginning of the linked list.
pop_back()
Andpop_front()
: Deletes the elements at the end and the beginning of the linked list.
insert()
: Insert an element at the specified position.
erase()
: Delete the element at the specified position.
begin()
ANDend()
: Returns an iterator pointing to one position after the start and end elements of the linked list.
size()
: Returns the number of elements in the linked list.
empty()
: Check if the linked list is empty.
clear()
: Clear all elements in the linked list.
Example usage
#include <iostream>
#include <list>
int main() {
std::list<int> myList;
myList.push_back(1);
myList.push_back(2);
myList.push_back(3);
myList.pop_front();
myList.insert(std::next(myList.begin()), 4);
for (const auto& num : myList) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
When using std::list
, you need to weigh its advantages and disadvantages, and choose the appropriate container according to the actual scenario. std::list
Might be a good choice when frequent insertion and deletion of elements is required, and random access is not required . However, it should be noted that due to the characteristics of the linked list, std::list
it is not suitable for scenarios that require fast random access to elements, because accessing elements at a certain position requires traversing the linked list.
Significant differences and advantages of std::list compared to other sequential containers such as std::vector and std::deque
Advantage:
High insertion and deletion efficiency: Since
std::list
it is a doubly linked list, the insertion and deletion operations are completed in constant time without involving reallocation of memory and copying of elements. This makes itstd::list
very efficient for large numbers of insert and delete operations.
Stability of iterators:std::list
Insertion and deletion operations will not invalidate the iterator unless the deletion is exactly the element pointed to by the iterator. This makes inserting and deleting operations more convenient and safe during traversal.
Relatively stable space occupancy:std::list
The space occupancy of is relatively stable, and insertion and deletion operations will not affect the space occupancy of other elements.
Disadvantages:
Does not support random access: Due to the structure of the linked list,
std::list
random access like an array is not supported. Accessing an element at a certain position requires traversing from the beginning or end of the linked list.
Additional pointer overhead:std::list
each element in the container needs to store pointers to previous and subsequent elements, which makes the space usage higher than other containers.
Low cache efficiency: Since the storage locations of the elements in the linked list are discontinuous in the memory, when accessing the elements of the linked list, the cache hit rate is low, which may affect performance.
Restriction on the use of iterators:std::list
iterators do not support arithmetic operations (such as + and -) similar to ordinary pointers, sostd::vector
iterator operations cannot be performed as flexibly as .
member type
list constructor
When using std::list
the class to create objects, different constructors can be used to meet different initialization needs. Each constructor and an example of its use are described in detail below:
1. default (1)
This constructor is used to create an empty std::list
container. It can accept an optional allocator argument specifying the memory allocation strategy.
std::list<int> myList; // 创建一个空的 std::list 容器
2. fill (2)
This constructor is used to create a std::list
container of n elements and initialize those elements to val
. You can val
create a container containing the same value by passing a different value. Likewise, an optional allocator parameter can also be passed.
std::list<int> myList(5, 42); // 创建一个包含 5 个元素,每个元素都是 42 的 std::list 容器
3.range (3)
This constructor [first, last)
creates a std::list
container using the elements in the iterator range. This allows you to initialize the container with an iterator range. Likewise, it also accepts an optional allocator argument.
std::vector<int> vec = {
1, 2, 3, 4, 5};
std::list<int> myList(vec.begin(), vec.end()); // 从迭代器范围内的元素创建 std::list 容器
4. copy (4)
This constructor is used to create an identical copy of an existing std::list
Container . x
It will x
copy all the elements in the new container. This is a copy constructor.
std::list<int> originalList = {
1, 2, 3, 4, 5};
std::list<int> copiedList(originalList); // 创建一个原容器的副本
These constructors provide different initialization methods to create std::list containers according to specific needs. According to your data source and other conditions, choose the appropriate constructor to create the container object.
list iterators (Iterators)
1. begin()
iterator begin() noexcept;
This version of begin()
returns an iterator that can be used to modify the elements in the container. noexcept
Indicates that this function will not throw an exception.
std::list<int> myList = {
1, 2, 3, 4, 5};
std::list<int>::iterator it = myList.begin(); // 获取可修改元素的迭代器
*it = 10; // 修改第一个元素的值为 10
const_iterator begin() const noexcept;
This version of begin()
returns a read-only iterator for accessing elements without modifying the container. const
Indicates that this function will not modify the container.
const std::list<int> myList = {
1, 2, 3, 4, 5};
std::list<int>::const_iterator cit = myList.begin(); // 获取只读元素的迭代器
int firstElement = *cit; // 读取第一个元素的值
2. end()
iterator end() noexcept;
This version of end()
returns an iterator that can be used to modify the elements in the container. noexcept
Indicates that this function will not throw an exception. The position pointed by this iterator is actually a virtual position after the end position of the container, so it does not point to any element in the container.
std::list<int> myList = {
1, 2, 3, 4, 5};
std::list<int>::iterator it = myList.end(); // 获取可修改元素的迭代器
--it; // 将迭代器前移一个位置,指向最后一个元素
*it = 20; // 修改最后一个元素的值为 20
const_iterator end() const noexcept;
This version of end()
returns a read-only iterator for accessing elements without modifying the container. const
Indicates that this function will not modify the container. Likewise, this iterator also points to the virtual position, after the last element in the container.
const std::list<int> myList = {
1, 2, 3, 4, 5};
std::list<int>::const_iterator cit = myList.end(); // 获取只读元素的迭代器
--cit; // 将迭代器前移一个位置,指向最后一个元素
int lastElement = *cit; // 读取最后一个元素的值
3. rbegin()
reverse_iterator rbegin() noexcept;
This version of rbegin()
returns a reverse iterator that can be used to modify elements inside the container. noexcept
Indicates that this function will not throw an exception. This reverse iterator points to the last element in the container, and --
the container can be traversed forward through the decrement operator.
std::list<int> myList = {
1, 2, 3, 4, 5};
std::list<int>::reverse_iterator rit = myList.rbegin(); // 获取可修改元素的反向迭代器
*rit = 10; // 修改最后一个元素的值为 10
++rit; // 将反向迭代器往前移动一个位置,指向倒数第二个元素
const_reverse_iterator rbegin() const noexcept;
This version of rbegin()
returns a read-only reverse iterator for accessing elements without modifying the container. const
Indicates that this function will not modify the container. This reverse iterator also points to the last element, and --
the container can be traversed forward through the decrement operator.
const std::list<int> myList = {
1, 2, 3, 4, 5};
std::list<int>::const_reverse_iterator crit = myList.rbegin(); // 获取只读元素的反向迭代器
int lastElement = *crit; // 读取最后一个元素的值
++crit; // 将反向迭代器往前移动一个位置,指向倒数第二个元素
4. rend()
reverse_iterator rend() nothrow;
This version of rend()
returns a reverse iterator that can be used to modify elements inside the container. nothrow
Indicates that this function will not throw an exception. This reverse iterator points to the position in the container, before the first element, and --
the container can be traversed forward through the decrement operator.
std::list<int> myList = {
1, 2, 3, 4, 5};
std::list<int>::reverse_iterator rit = myList.rend(); // 获取可修改元素的反向迭代器
--rit; // 将反向迭代器往前移动一个位置,指向最后一个元素
*rit = 10; // 修改最后一个元素的值为 10
const_reverse_iterator rend() const nothrow;
This version of rend()
returns a read-only reverse iterator for accessing elements without modifying the container. const
Indicates that this function will not modify the container. This reverse iterator also points to the position of the container, before the first element, which can be traversed forward through the decrement operator.
const std::list<int> myList = {
1, 2, 3, 4, 5};
std::list<int>::const_reverse_iterator crit = myList.rend(); // 获取只读元素的反向迭代器
--crit; // 将反向迭代器往前移动一个位置,指向最后一个元素
int lastElement = *crit; // 读取最后一个元素的值
5. cbegin()、cend()、crbegin()、crend()
const_iterator cbegin() const noexcept;
This member function returns a constant iterator pointing to the elements of the container, pointing to the beginning of the container. With constant iterators, you can iterate over the elements of the container, but you cannot modify them.
const_iterator cend() const noexcept;
This member function returns a constant iterator to the elements of the container, pointing to the end of the container. This iterator represents a position past the end of the container, and is typically used as a termination condition for iterator loops.
std::list<int> myList = {
1, 2, 3, 4, 5};
std::list<int>::const_iterator cit = myList.cbegin(); // 获取常量迭代器
for (; cit != myList.cend(); ++cit) {
std::cout << *cit << " "; // 输出容器中的元素,不修改它们
}
const_reverse_iterator crbegin() const noexcept;
This member function returns a const reverse iterator pointing to the elements of the container, pointing to the reverse starting position of the container. With a const reverse iterator, you can traverse the elements of the container in reverse, but you cannot modify them.
const_reverse_iterator crend() const noexcept;
This member function returns a const reverse iterator pointing to the elements of the container, pointing to the reverse end position of the container. This iterator represents a position beyond the head of the container, and is typically used as the termination condition for a reverse iterator loop.
std::list<int> myList = {
1, 2, 3, 4, 5};
std::list<int>::const_reverse_iterator crit = myList.crbegin(); // 获取常量反向迭代器
for (; crit != myList.crend(); ++crit) {
std::cout << *crit << " "; // 反向输出容器中的元素,不修改它们
}
list capacity function (Capacity) and element access function (Element access)
1. empty()
empty()
Yes std::list
A member function of the container, used to determine whether the container is empty. It returns a boolean indicating whether the container contains no elements. The function declaration is as follows:
bool empty() const noexcept;
Return Value : true if the container is empty, false otherwise.
Example usage :
#include <iostream>
#include <list>
int main() {
std::list<int> myList;
if (myList.empty()) {
std::cout << "The list is empty." << std::endl;
} else {
std::cout << "The list is not empty." << std::endl;
}
myList.push_back(42);
if (myList.empty()) {
std::cout << "The list is empty." << std::endl;
} else {
std::cout << "The list is not empty." << std::endl;
}
return 0;
}
In the above example, first create an empty std::list
container myList
, then use empty()
the function to check whether the container is empty, and output the corresponding information. Then, by push_back
adding an element to the container, and using empty()
the function again to check whether the container is empty, output the appropriate information.
2. size()
size()
is std::list
a member function of the container that returns the number of elements in the container. It returns an unsigned integer type representing the number of elements in the container. The function declaration is as follows:
size_type size() const noexcept;
Return Value : Returns the number of elements in the container, ie the size.
Example usage :
#include <iostream>
#include <list>
int main() {
std::list<int> myList;
myList.push_back(1);
myList.push_back(2);
myList.push_back(3);
std::cout << "Size of the list: " << myList.size() << std::endl;
return 0;
}
In the example above, we first create a std::list
container myList
and then use push_back
the function to add three elements to the container. Then use size()
the function to get the size of the container and output it to standard output.
3. max_size()
max_size()
is std::list
a member function of the container that returns the maximum number of elements the container may hold, usually subject to system memory constraints. It returns an unsigned integer type representing the maximum size of the container. The function signature is as follows:
size_type max_size() const noexcept;
Return Value : Returns the maximum number of elements that the container may hold.
Example usage :
#include <iostream>
#include <list>
int main() {
std::list<int> myList;
std::cout << "Max size of the list: " << myList.max_size() << std::endl;
return 0;
}
In the example above, we created an empty std::list
container myList
, then used max_size()
the function to get the maximum size of the container and output it to standard output. Note that the actual maximum size available depends on system memory and other resource limitations.
4. front()
front()
Is std::list
a member function of the container that returns a reference to the first element in the container. There are two versions of this function, one for objects of modifiable containers and one for objects of read-only (const) containers. The signature of the function is as follows:
reference front();
const_reference front() const;
reference : Returns a very reference to the first element in the container.
const_reference : Only const
when called on a container object, returns a constant reference to the first element in the container.
Example usage :
#include <iostream>
#include <list>
int main() {
std::list<int> myList = {
10, 20, 30};
int& firstElement = myList.front();
const int& constFirstElement = myList.front();
std::cout << "First element: " << firstElement << std::endl;
std::cout << "Const first element: " << constFirstElement << std::endl;
return 0;
}
In the example above, we created a std::list
container myList
with three integer elements. We use front()
the function to get a reference to the first element in the container, store it as a modifiable reference firstElement
and a read-only constant reference respectively constFirstElement
, and output them to standard output.
5. back()
back()
Is a member function of the std::list container, used to return a reference to the last element in the container. There are two versions of this function, one for objects of modifiable containers and one for objects of read-only (const) containers. The signature of the function is as follows:
reference back();
const_reference back() const;
reference : Returns a very reference to the last element in the container.
const_reference : Only when called on a const container object, returns a constant reference to the last element in the container.
Example usage :
#include <iostream>
#include <list>
int main() {
std::list<int> myList = {
10, 20, 30};
int& lastElement = myList.back();
const int& constLastElement = myList.back();
std::cout << "Last element: " << lastElement << std::endl;
std::cout << "Const last element: " << constLastElement << std::endl;
return 0;
}
In the above example, we created a std::list
container myList
with three integer elements. We use back()
the function to get a reference to the last element in the container, store it as a modifiable reference lastElement
and a read-only constant reference respectively constLastElement
, and output them to standard output.
List add, delete, check and modify function (Modifiers)
1. assign
assign
Yes std::list
A member function of the container, used to replace the contents of the container with new elements. There are three different versions of this function:
Use iterator ranges:
template <class InputIterator>
void assign (InputIterator first, InputIterator last);
This version accepts two iterator arguments first
, and last
, to specify a range. It replaces the contents of the container with [first, last)
the elements within the scope.
Use repeating elements:
void assign (size_type n, const value_type& val);
This version accepts an integer argument n
, and a value val
. It will replace the contents of the container with elements with n
a value val
of .
Use an initializer list:
void assign (initializer_list<value_type> il);
This version accepts an initializer list as an argument. It replaces the contents of the container with the elements in the initializer list.
Example usage:
#include <iostream>
#include <list>
int main() {
std::list<int> myList;
myList.assign({
1, 2, 3, 4, 5}); // 使用初始化列表
std::cout << "Size after assigning with initializer list: " << myList.size() << std::endl;
myList.assign(3, 100); // 使用重复元素
std::cout << "Size after assigning with repeated elements: " << myList.size() << std::endl;
std::list<int> anotherList = {
10, 20, 30, 40};
myList.assign(anotherList.begin(), anotherList.end()); // 使用迭代器范围
std::cout << "Size after assigning with iterator range: " << myList.size() << std::endl;
return 0;
}
In the example above, we first created an empty std::list
container myList
. Then use different versions of assign
the function to replace the contents of the container separately. Finally, we output the size of the container to verify that the operation was successful.
2. emplace_front
template <class... Args>
void emplace_front (Args&&... args);
emplace_front
Is std::list
a member function of the container, used to insert a new element at the beginning of the container. It avoids extra copy or move operations by directly constructing elements at the specified positions.
This function accepts a variable number of arguments Args...
that will be used to construct the new element. Use emplace_front
to insert elements directly at the beginning of the container without creating a temporary object and then inserting.
Example usage:
#include <iostream>
#include <list>
struct Person {
std::string name;
int age;
Person(const std::string& n, int a) : name(n), age(a) {
std::cout << "Constructing " << name << std::endl;
}
};
int main() {
std::list<Person> personList;
personList.emplace_front("zhangsan", 25);
personList.emplace_front("lisi", 30);
personList.emplace_front("wangwu", 28);
std::cout << "Person list contents:" << std::endl;
for (const auto& person : personList) {
std::cout << "Name: " << person.name << ", Age: " << person.age << std::endl;
}
return 0;
}
In the above example, we first defined a Person
structure named with two member variables: name
and age
. Then we create an empty std::list
container personList
, use emplace_front
the function to insert several new Person
objects at the beginning of the container, and construct directly at the insertion position.
Note that emplace_front
the parameter of is passed to Person
the constructor of the type, which is used to construct the new Person
object. Doing so avoids additional copy or move operations and improves efficiency.
3. push_front
push_front
Is std::list
a member function of the container, used to insert a new element at the beginning of the container.
There are two versions of this function:
void push_front (const value_type& val);
: Accept a constant reference parameter, which will create a new element and copy the value of the parameter to the new element.
void push_front (value_type&& val);
: Accepts an rvalue reference parameter, which is used to move construct a new element. This can avoid additional copy operations and improve efficiency.
Example usage:
#include <iostream>
#include <list>
int main() {
std::list<int> myList;
int value = 20;
myList.push_front(value); // Copy insert
std::cout << "List contents:" << std::endl;
for (const auto& num : myList) {
std::cout << num << " ";
}
std::cout << std::endl;
myList.push_front(25); // Move insert
std::cout << "List contents after move insert:" << std::endl;
for (const auto& num : myList) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
In the above example, we first create an empty std::list
container myList
, and then use push_front
the function to perform constant reference copy insertion and rvalue reference move insertion operations respectively. As you can see, the rvalue reference version is push_front
more efficient because it avoids the extra copy operation.
4. pop_front
void pop_front();
is a member function for removing an element from the beginning of a std::list. It removes the first element in the list and reduces the size of the list by one unit.
Example usage:
std::list<int> myList = {
1, 2, 3, 4, 5};
myList.pop_front(); // 移除第一个元素
In the above example, pop_front()
the 1 element would be removed, making the list {2, 3, 4, 5}.
5. emplace_back
template <class... Args> void emplace_back (Args&&... args);
is a std::list
function that inserts a new element at the end of the . It allows you to construct elements directly at the end of the list by passing the parameters required to construct the element, avoiding additional copy or move operations.
Example usage:
std::list<std::string> myList;
myList.emplace_back("Hello");
myList.emplace_back("World");
In the above example, emplace_back
the function constructs two string elements, "Hello"
and , directly at the end of the list "World"
.
This function is useful to avoid extra element construction and copy operations, especially when storing large objects in containers, which can improve performance.
6. push_back
void push_back (const value_type& val);
is std::list
a member function of the container used to insert a new element at the end of the list. It takes a constant reference as an argument and inserts the passed value at the end of the list.
Example usage:
std::list<int> myList;
myList.push_back(10);
myList.push_back(20);
myList.push_back(30);
In the above example, the function inserts the integers and push_back
respectively at the end of the list.10、20
30
This function is relatively simple in operation, but may involve memory allocation and element copy operations. If the inserted elements are relatively large, it may cause additional performance overhead.
7. pop_back
void pop_back();
Is std::list
a member function of the container, used to delete the last element in the list. It removes the last element of the list from the container and releases the corresponding memory resource.
Example usage:
std::list<int> myList;
myList.push_back(10);
myList.push_back(20);
myList.push_back(30);
myList.pop_back();
In the example above, pop_back
the function removes elements from the list 30
, making the list [10, 20]
.
It should be noted that pop_back
the list must not be empty before calling the function, otherwise undefined behavior will occur. You can use empty()
the function to check whether the list is empty.
8. location
template <class... Args> iterator emplace (const_iterator position, Args&&... args);
Yes std::list
A member function of the container, used to insert a new element at the specified position, and pass the parameters of the element constructor to the inserted element.
Parameter description :
position
: Iterator to the position where the new element is to be inserted.
args
: The parameter passed to the constructor of the new element.
This function returns an iterator pointing to the newly inserted element.
Example usage:
std::list<int> myList = {
10, 20, 30};
auto it = myList.begin();
++it; // 移动到第二个元素的位置
myList.emplace(it, 25); // 在第二个元素位置插入值为 25 的元素
In the above example, emplace
the function inserts a 25
new element with value at the position of the second element, making the list become [10, 25, 20, 30]
. The returned iterator points to the inserted element 25
.
This function is suitable for inserting elements at any position, and can be passed directly to the element's constructor via parameters.
9. insert
iterator insert (iterator position, const value_type& val);
void insert (iterator position, size_type n, const value_type& val);
template <class InputIterator>
void insert (iterator position, InputIterator first, InputIterator last);
iterator insert (iterator position, const value_type& val);
Yes std::list
A member function of the container, used to insert a new element at the specified position, and the value of the new element is val
determined by the parameter.
Parameter Description:
position
: Iterator to the position where the new element is to be inserted.
val
: The value of the element to insert.
This function returns an iterator pointing to the inserted element.
Example usage:
std::list<int> myList = {
10, 20, 30};
auto it = myList.begin();
++it; // 移动到第二个元素的位置
myList.insert(it, 25); // 在第二个元素位置插入值为 25 的元素
void insert (iterator position, size_type n, const value_type& val);
is another version of the insert function that inserts a specified number of elements of the same value.
Parameter Description:
position
: Iterator to the position where the new element is to be inserted.
n
: The number of identical elements to insert.
val
: The value of the element to insert.
template <class InputIterator> void insert (iterator position, InputIterator first, InputIterator last);
is another version of the insert function that inserts a range of elements from a specified range of iterators.
Parameter Description:
position
: Iterator to the position where the new element is to be inserted.
first
and last
: Iterator to the range of elements to insert.
These insert
functions provide different insertion methods, giving you the flexibility to add elements to the list as needed.
10. erase
iterator erase (iterator position);
and iterator erase (iterator first, iterator last);
is std::list
a member function of the container that removes one or more elements from the list.
iterator erase (iterator position);
Deletes the element at the specified position and returns an iterator pointing to the next element.
Parameter Description:
position
: Iterator to the position of the element to remove.
Return value : an iterator pointing to the element after the deleted element.
Example usage:
std::list<int> myList = {
10, 20, 30, 40};
auto it = myList.begin();
++it; // 移动到第二个元素的位置
myList.erase(it); // 删除第二个元素
iterator erase (iterator first, iterator last);
Deletes the elements in the specified range and returns an iterator pointing to the elements after the deleted range.
Parameter Description:
first
and last
: Iterator to the range of elements to delete, including first but not last.
Return Value: An iterator pointing to the elements after the deleted range.
Example usage:
std::list<int> myList = {
10, 20, 30, 40};
auto it1 = myList.begin();
auto it2 = myList.begin();
std::advance(it2, 2); // 移动到第三个元素的位置
myList.erase(it1, it2); // 删除第一个和第二个元素
These functions allow you to remove one or more elements from the list as needed, and return the proper iterator for subsequent operations.
11. swap
void swap(list& x);
Is std::list
a member function of the container, which is used to exchange the contents of the current list with another list x
.
Parameter Description:
x
: Another list to swap content with the current list.
Example usage:
#include <iostream>
#include <list>
int main() {
std::list<int> myList1 = {
1, 2, 3};
std::list<int> myList2 = {
4, 5, 6};
myList1.swap(myList2); // 交换两个列表的内容
std::cout << "myList1: ";
for (int num : myList1) {
std::cout << num << " ";
}
std::cout << std::endl;
std::cout << "myList2: ";
for (int num : myList2) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
In the above example, the contents of myList1
and myList2
are swapped, resulting in and being displayed in the output, 4 5 6
respectively 1 2 3
. This function is very useful for exchanging content between different lists.
12. resize
void resize(size_type n, value_type val = value_type());
is std::list
a member function of the container, used to adjust the size of the list.
Parameter Description:
n
: Specifies the resized size.
val
: The value used to populate new elements when the list is expanded. The default value value_type()
is the value created by the type's default constructor.
This function resizes the list to the specified size by adding or removing elements from the end of the list n
. If the new size is larger than the current size, the new element will be filled with the specified value val
. If the new size is smaller than the current size, redundant elements will be removed.
Example usage:
#include <iostream>
#include <list>
int main() {
std::list<int> myList = {
1, 2, 3, 4, 5};
myList.resize(3); // 调整列表大小为3
std::cout << "myList after resize to 3: ";
for (int num : myList) {
std::cout << num << " ";
}
std::cout << std::endl;
myList.resize(5, 0); // 调整列表大小为5,并用0填充新元素
std::cout << "myList after resize to 5 with filling 0: ";
for (int num : myList) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
In the above example, resize(3)
after first calling , only the first 3 elements in the list remain, and then after calling resize(5, 0)
, there are a total of 5
1 elements in the list, of which the newly added 2
elements are filled 0
.
13. clear
void clear();
Yes std::list
A member function of the container, which is used to clear all elements in the list, making the list an empty list.
This function will delete all elements in the list and make the list empty, but it will not release the memory space occupied by the list, so the capacity of the list will not change. This effectively reclaims resources occupied by elements, but reserves capacity to reduce frequent memory allocation and deallocation operations to improve performance.
Example usage:
#include <iostream>
#include <list>
int main() {
std::list<int> myList = {
1, 2, 3, 4, 5};
std::cout << "myList before clear: ";
for (int num : myList) {
std::cout << num << " ";
}
std::cout << std::endl;
myList.clear(); // 清空列表
std::cout << "myList after clear: ";
for (int num : myList) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
In the above example, the list elements before clearing are first output, and then after calling clear()
, all elements in the list are deleted, and the list elements after clearing are output, and the list is empty at this time.
list operation function (Operations)
1. splice
void splice (iterator position, list& x);
This member function is used to x
move all elements in another list to the current list and insert them position
before the specified position. x
The list becomes an empty list after being moved.
Example usage:
#include <iostream>
#include <list>
int main() {
std::list<int> myList1 = {
1, 2, 3};
std::list<int> myList2 = {
4, 5, 6};
auto it = myList1.begin();
std::advance(it, 2);
myList1.splice(it, myList2); // 将 myList2 的元素插入到 myList1 中
std::cout << "myList1 after splice: ";
for (int num : myList1) {
std::cout << num << " ";
}
std::cout << std::endl;
std::cout << "myList2 after splice: ";
for (int num : myList2) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
void splice (iterator position, list& x, iterator i);
This member function is used to x
move the elements in another list to the current list and insert them position
before the specified position, but only move the elements pointed to by x
the iterator in another list.i
Example usage:
#include <iostream>
#include <list>
int main() {
std::list<int> myList1 = {
1, 2, 3};
std::list<int> myList2 = {
4, 5, 6};
auto it1 = myList1.begin();
std::advance(it1, 1);
auto it2 = myList2.begin();
myList1.splice(it1, myList2, it2); // 将 myList2 中的第一个元素插入到 myList1 中
std::cout << "myList1 after splice: ";
for (int num : myList1) {
std::cout << num << " ";
}
std::cout << std::endl;
std::cout << "myList2 after splice: ";
for (int num : myList2) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
void splice (iterator position, list& x, iterator first, iterator last);
This member function is used to move x
a range of elements in another list [first, last)
to the current list and insert it position
before the specified position.
Example usage:
#include <iostream>
#include <list>
int main() {
std::list<int> myList1 = {
1, 2, 3};
std::list<int> myList2 = {
4, 5, 6};
auto it1 = myList1.begin();
std::advance(it1, 1);
auto it2_first = myList2.begin();
auto it2_last = myList2.begin();
std::advance(it2_last, 2);
myList1.splice(it1, myList2, it2_first, it2_last); // 将 myList2 中的前两个元素插入到 myList1 中
std::cout << "myList1 after splice: ";
for (int num : myList1) {
std::cout << num << " ";
}
std::cout << std::endl;
std::cout << "myList2 after splice: ";
for (int num : myList2) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
These splice
functions allow you to move elements within a list, move from one list to another, or rearrange the position of elements within the same list without copying and deleting elements.
2. remove
void remove (const value_type& val);
val
This member function is used to remove all elements equal to the given value from the list .
Example usage:
#include <iostream>
#include <list>
int main() {
std::list<int> myList = {
1, 2, 3, 2, 4, 2, 5};
myList.remove(2); // 移除列表中所有值为 2 的元素
std::cout << "myList after remove: ";
for (int num : myList) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
In the example, elements myList
in the list whose value is is removed and the final output is .2
"1 3 4 5"
3. remove_if
template <class Predicate> void remove_if (Predicate pred);
pred
This member function is used to remove elements satisfying a certain condition according to the given predicate function .
The predicate function pred
takes one parameter and returns a Boolean value, which is used to determine whether the element needs to be removed. If the predicate returns true
, the element will be removed.
Example usage:
#include <iostream>
#include <list>
bool isEven(int num) {
return num % 2 == 0;
}
int main() {
std::list<int> myList = {
1, 2, 3, 4, 5, 6, 7, 8, 9};
myList.remove_if(isEven); // 移除列表中所有偶数
std::cout << "myList after remove_if: ";
for (int num : myList) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
In the example, myList
the even elements in the list are removed and the final output is "1 3 5 7 9"
. function isEven
is aPredicate function, used to judge whether it is an even number。
4. unique
void unique();
This member function is used to remove adjacent duplicate elements in a list. It keeps only the first occurrence of the repeated element and removes subsequent repeated elements.
Example usage:
#include <iostream>
#include <list>
int main() {
std::list<int> myList = {
1, 2, 2, 3, 4, 4, 4, 5};
myList.unique(); // 移除相邻的重复元素
std::cout << "myList after unique: ";
for (int num : myList) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
In the example, myList
adjacent duplicate elements in the list are removed and the final output is "1 2 3 4 5"
.
template <class BinaryPredicate> void unique (BinaryPredicate binary_pred);
When removing adjacent repeated elements, this member function uses a custom binary predicate function binary_pred
to determine whether it is a repeated element. The predicate function accepts two parameters and returns a Boolean value that is used to determine whether two elements are equal.
Example usage:
#include <iostream>
#include <list>
bool isEqual(int a, int b) {
return a == b;
}
int main() {
std::list<int> myList = {
1, 2, 2, 3, 4, 4, 4, 5};
myList.unique(isEqual); // 使用 isEqual 判断是否为重复元素
std::cout << "myList after unique with custom predicate: ";
for (int num : myList) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
In the example, the user-defined predicate function is used isEqual
to judge whether adjacent elements are equal, remove adjacent duplicate elements, and the final output is "1 2 3 4 5"
.
5. merge
void merge(list& x);
This member function is used to x
merge another list into the current list, and the merged list will be sorted in ascending order.
Example usage:
#include <iostream>
#include <list>
int main() {
std::list<int> myList1 = {
1, 3, 5};
std::list<int> myList2 = {
2, 4, 6};
myList1.merge(myList2); // 将 myList2 合并到 myList1 中
std::cout << "myList1 after merge: ";
for (int num : myList1) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
In the example, myList2
the lists are merged into myList1
, the merged list is sorted in ascending order, and the final output is "1 2 3 4 5 6"
.
template <class Compare> void merge(list& x, Compare comp);
This member function is similar to the above merge
function, but it allows to provide a custom comparison function comp to determine the merged order.
Example usage:
#include <iostream>
#include <list>
bool descendingOrder(int a, int b) {
return a > b;
}
int main() {
std::list<int> myList1 = {
5, 3, 1};
std::list<int> myList2 = {
6, 4, 2};
myList1.merge(myList2, descendingOrder); // 使用自定义比较函数合并
std::cout << "myList1 after merge with custom comparison: ";
for (int num : myList1) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
descendingOrder
In the example, the list is myList2
merged into by a custom comparison function myList1
, the merged list is sorted in descending order, and the final output is "6 5 4 3 2 1"
.
6. sort
void sort();
This member function is used to sort the list in ascending order, using <
the operator for comparison by default.
Example usage:
#include <iostream>
#include <list>
int main() {
std::list<int> myList = {
5, 3, 1, 4, 2};
myList.sort(); // 对列表进行升序排序
std::cout << "myList after sorting: ";
for (int num : myList) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
In the example, the elements in the list become sorted "1 2 3 4 5"
.
template <class Compare> void sort(Compare comp);
This member function is similar to the one above sort
, but it allows a custom comparison function to be provided comp
to determine the sort order.
Example usage:
#include <iostream>
#include <list>
bool descendingOrder(int a, int b) {
return a > b;
}
int main() {
std::list<int> myList = {
5, 3, 1, 4, 2};
myList.sort(descendingOrder); // 使用自定义比较函数进行降序排序
std::cout << "myList after custom sorting: ";
for (int num : myList) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
In the example, through a custom comparison function descendingOrder
, the elements in the list become sorted "5 4 3 2 1"
.
7. reverse
void reverse();
The function is used to sort the elements in the list in reverse order.
Example usage:
#include <iostream>
#include <list>
int main() {
std::list<int> myList = {
1, 2, 3, 4, 5};
myList.reverse(); // 将列表中的元素逆序排列
std::cout << "myList after reversing: ";
for (int num : myList) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
In the example, the elements in the list are sorted in reverse order to become "5 4 3 2 1"
.
The iterator of the list is invalid
Iterator invalidation means that the node pointed to by the iterator is invalid, that is, the node is deleted. Because the underlying structure of the list is a two-way circular linked list with the leading node, the iterator of the list will not be invalidated when it is inserted into the list. It will only be invalidated when it is deleted, and only the iteration pointing to the deleted node will be invalidated. , other iterators are not affected.
When using std::list
to delete, it may invalidate the iterator. Here is an example:
#include <iostream>
#include <list>
int main() {
std::list<int> myList = {
1, 2, 3, 4, 5};
auto it = myList.begin();
++it; // Move the iterator to the second element
myList.erase(it); // Erase the second element
for (auto num : myList) {
std::cout << num << " ";
}
return 0;
}
In the above example, when we use erase
the function to delete the element at the second element position, the iterator it
will be invalid because the element it points to has been deleted. If we try to use an invalid iterator, it may result in undefined behavior.
To fix this, use erase
the return value of the function, which returns an iterator pointing to the next valid element:
#include <iostream>
#include <list>
int main() {
std::list<int> myList = {
1, 2, 3, 4, 5};
auto it = myList.begin();
++it; // Move the iterator to the second element
it = myList.erase(it); // Erase the second element and update the iterator
for (auto num : myList) {
std::cout << num << " ";
}
return 0;
}
In this revised example, we erase
update the iterator with the return value of the function it
to ensure that it points to a valid element. This avoids the problems caused by using invalid iterators.
epilogue
Interested friends can pay attention to the author, if you think the content is good, please give a one-click triple link, you crab crab! ! !
It is not easy to make, please point out if there are any inaccuracies
Thank you for your visit, UU watching is the motivation for me to persevere.
With the catalyst of time, let us all become better people from each other! ! !