2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
The bottom layer of the list is a bidirectional circular linked list structure with a sentinel position.
Compared with the single linked list structure of forward_list, the iterator of list is a bidirectional iterator
Compared with sequential containers such as vector, list is more efficient in inserting and deleting at any position, but does not support random access at any position.
List is a template class. When using it, we need to give the type of the element.When using the list class, you need to include the header file<list>
list();
For example:
- void test()
- {
- list<int> lt;
- }
list(size_type n, const value_type& val = value_type());
For example:
- void test()
- {
- list<int> lt(3, 1);
- for (auto i : lt)
- {
- cout << i << " ";
- }
- }
operation result:
list(const list& x);
For example:
- void test()
- {
- list<int> lt(3, 1);
- list<int> lt1(lt);
- for (auto i : lt1)
- {
- cout << i << " ";
- }
- }
operation result:
- Template<class InputIterator>
-
- list(InputIterator first, InputIterator last);
For example:
- void test()
- {
- list<int> lt(3, 1);
- list<int> lt1(lt.begin(), lt.end());
- for (auto i : lt1)
- {
- cout << i << " ";
- }
- }
operation result:
It’s still the same old things, let me talk about them one by one.
size:returnLinked ListThe number of elements in the container.
size_type size() const;
empty:returnListIs the container empty (i.e. itssizeis 0).
(Note: This function does not modify the container in any way. To clearLinked ListContainer contents, seelist::clear。)
bool empty() const;
max_size(uncommon): returnLinked ListThe maximum number of elements the container can hold.
(Due to known system or library implementation limitations, this is the maximum potential that the container can achieve.size, but the container is by no means guaranteed to reach that size: it may still fail to allocate storage at any time before that size is reached.)
size_type max_size() const;
resize:Resize the container to containnelements.
ifnSmaller than the current containersize, the content will be reduced to its previousnelements, removing those that exceed that limit (and destroying them).
ifnLarger than the current containersize, the contents are extended by inserting the required number of elements at the end to achievenIf you specifyval, then the new element will be initialized tovalOtherwise, they are value-initialized.
(Note that this function changes the actual contents of the container by inserting or erasing elements from it.)
void resize (size_type n, value_type val = value_type());
For example:
-
- void test()
- {
- list<int> lt(3, 1);
- /*list<int> lt1(lt);*/
- list<int> lt1(lt.begin(), lt.end());
- list<int> lt2;
- cout << lt1.size() <<endl;
- cout << lt1.empty() <<endl;
- cout << lt2.empty() <<endl;
- lt1.resize(10);
- cout << lt1.size() << endl;
- for (auto i : lt1)
- {
- cout << i << " ";
- }
- }
-
-
operation result:
- iterator begin();
-
- const_iterator begin() const;
-
- iterator end();
-
- const_iterator end() const;
Iterator: used to get the position of the first node and the last node in the linked listNext position (i.e. sentinel position)
For example:
- void test()
- {
- list<int> lt(5, 2);
- list<int> ::iterator it = lt.begin();
- while (it != lt.end())
- {
- cout << *it << " ";
- ++it;
- }
- }
operation result:
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;
Reverse iterator, rbegin gets the position of the last node in the container, and rend gets the position of the sentinel in the container
- void test()
- {
- list<int> lt = { 1,23,4,4,5,2 };
- list<int> ::reverse_iterator rit = lt.rbegin();
- while (rit != lt.rend())
- {
- cout << *rit << " ";
- ++rit;
- }
- }
operation result:
Note: The reverse iterator rit should also use ++ instead of --
front:
reference front();
const_reference front() const;
Returns a reference to the data stored in the first node in the linked list
back:
reference back();
const_reference back() const;
Returns a reference to the data stored in the last node in the linked list
For example:
- void test()
- {
- list<int> lt = {213123,123,34524,213};
- cout << lt.front() << endl;
- cout << lt.back() << endl;
-
- }
operation result:
push_front is called head insertion, inserting an element from the head of the linked list
void push_front(const value_type& val);
pop_front is called head deletion, which deletes an element from the head of the linked list
void pop_front();
void pop_front();
For example:
- void test()
- {
- list<int> lt = {213123,123,34524,213};
- cout << lt.front() << endl;
- lt.push_front(21345);
- cout << lt.front() << endl;
- lt.pop_front();
- cout << lt.front() << endl;
- }
operation result:
push_back is called tail insertion, inserting an element from the end of the linked list
void push_back(const value_type& val);
pop_back is called tail deletion, which deletes an element from the tail of the linked list
void pop_back();
For example:
- void test()
- {
- list<int> lt = {213123,123,34524,213};
- cout << lt.back() << endl;
- lt.push_back(21345);
- cout << lt.back() << endl;
- lt.pop_back();
- cout << lt.back() << endl;
- }
operation result:
- template <class InputIterator, class T>
-
- InputIterator find(InputIterator first, InputIterator last, const T& val);
Searches for val in two iterator intervals and returns the iterator at that location.
For example:
- void test()
- {
- list<int> lt;
- for (int i = 0; i < 3; i++)
- {
- lt.push_back(i);
- }
- list<int>::iterator pos = find(lt.begin(), lt.end(), 1);
- *pos = 114514;
- for (auto i : lt)
- {
- cout << i << " ";
- }
- }
operation result:
Note: This function is not a member function of list, but a function in the standard library. Multiple containers share the find function.
As you can see, we can directly dereference the iterator of the list and modify its content, but shouldn't the iterator point to the node? Why can dereferencing it modify the data?
In fact, the iterator of the list is not simulated using native pointers, but requires underlying encapsulation, which will be reflected in the source code of the simulated implementation of the list.
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);
Insert one or more elements before position
For example:
- void test()
- {
- list<int> lt;
- for (int i = 0; i < 3; i++)
- {
- lt.push_back(i);
- }
- list<int>::iterator pos = find(lt.begin(), lt.end(), 1);
- lt.insert(pos, 8848);
- for (auto i : lt)
- {
- cout << i << " ";
- }
- }
operation result:
Careful students may have discovered that the insert operation of list isWill not cause iterators to become invalidBecause the node pointed to by pos does not change, the relative position does not change.
However, the deletion operation of the list will definitely cause the iterator to become invalid, and only the iterator pointing to the deleted node will become invalid, and other iterators will not be affected.
- iterator erase(iterator position);
-
- iterator erase(iterator first, iterator last);
Delete the element at position or all elements in the interval [first, last)
For example:
- void test()
- {
- list<int> lt;
- for (int i = 0; i < 3; i++)
- {
- lt.push_back(i);
- }
- list<int>::iterator pos = find(lt.begin(), lt.end(), 1);
- lt.erase(lt.begin());
- for (auto i : lt)
- {
- cout << i << " ";
- }
- }
operation result:
- void test()
- {
- list<int> lt;
- for (int i = 0; i < 3; i++)
- {
- lt.push_back(i);
- }
- list<int>::iterator pos = find(lt.begin(), lt.end(), 2);
- lt.erase(lt.begin(),pos);
- for (auto i : lt)
- {
- cout << i << " ";
- }
- }
operation result:
void swap(vector& x);
Swap two list objects
For example:
- void test()
- {
- list<int> lt;
- list<int> lt2(6, 12);
- for (int i = 0; i < 10; i++)
- {
- lt.push_back(i);
- }
- lt.swap(lt2);
- for (auto i : lt2)
- {
- cout << i << " ";
- }
- cout << endl;
- }
operation result:
template <class InputIterator>
void assign(InputIterator first, InputIterator last);
void assign(size_type n, const value_type& val);
Assign new content to the list, replace its current content and modify the number of nodes
For example:
- void test()
- {
- list<int> lt;
- for (int i = 0; i < 10; i++)
- {
- lt.push_back(i);
- }
- lt.assign(4, 0);
- for (auto i : lt)
- {
- cout << i << " ";
- }
- }
operation result:
void clear();
Delete all nodes in the linked list
For example:
- void test()
- {
- list<int> lt;
- for (int i = 0; i < 10; i++)
- {
- lt.push_back(i);
- }
- lt.clear();
- cout << lt.size() << endl;
- }
operation result:
void sort();
template<class Compare>
void sort(Compare comp);
Due to the special structure of the list, the sort function in the standard library cannot be used, because the iterator cannot perform subtraction operations.
And in the C++ documentation, we can see that the sort in the standard library also limits the iterator type to be able to perform random access (RandomAccess)
- default (1)
- template <class RandomAccessIterator>
- void sort (RandomAccessIterator first, RandomAccessIterator last);
- custom (2)
- template <class RandomAccessIterator, class Compare>
- void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
Iterators have several functional categories:
- One-way iterator, can only perform ++
- Bidirectional iterator, can be ++ and --
- Random iterator, can be ++, --, + and -
But the list sort function is unnecessary, because sorting the linked list directly is much slower than copying it to a vector, sorting it, and then copying it back to the linked list.
template <class BidirectionalIterator> void reverse (BidirectionalIterator first, BidirectionalIterator last);
Reverse the linked list
For example:
- void test()
- {
- list<int> lt;
- for (int i = 0; i < 10; i++)
- {
- lt.push_back(i);
- }
- for (auto i : lt)
- {
- cout << i << " ";
- }
- cout << endl;
- lt.reverse();
- for (auto i : lt)
- {
- cout << i << " ";
- }
- cout << endl;
-
- }
operation result:
If there are any errors, please feel free to point them out.