Table of contents
The bottom layer of list is actually a doubly linked list structure.
Use of list
Constructor and assignment overloading
Constructor | illustrate |
---|---|
list() | No-argument construction |
list (size_type n, const value_type& val = value_type()) | The constructed list contains n elements whose value is val |
list (const list& x) | copy constructor |
list (InputIterator first, InputIterator last) | Constructs a list with elements in the range [first, last) |
The constructor is used the same as the previous container
void test1()
{
list<int> lt1;//无参构造
list<int> lt2(10, 1);//1,1,1,1,1,1,1,1,1,1
list<int> lt3(lt2);//拷贝构造
list<int> lt4(lt2.begin(), lt2.end());
}
Assignment overloading
list& operator= (const list& x);
void test1()
{
list<int> lt1;//无参构造
list<int> lt2(10, 1);//1,1,1,1,1,1,1,1,1,1
list<int> lt3(lt2);//拷贝构造
list<int> lt4(lt2.begin(), lt2.end());
list<int> lt5;
lt5 = lt4;//赋值重载
}
Iterator (most important)
There are three types of iterators: one-way iterators, two-way iterators, and random iterators
One-way iterator: supports ++ For example, the iterator type of forward_list and hash is a one-way iterator
Bidirectional iterator: supports ++, - - For example, the iterator type of list, map, set is a two-way iterator
Random iterator: Supports ++, - -, +, -. For example, the iterator types of vector, string, and deque are random iterators.
Random iterators can be thought of as special bidirectional iterators, and bidirectional iterators can be thought of as special unidirectional iterators
The iterator of list is different from vector
and The type of iterator is determined by the underlying structure of the containerstring
vector
The bottom layer of and string
is continuous, so their iterators are actually pointers, so they support ++, –, +, -, and the type is a random iterator
However list
, the bottom layer of the . to iterator
For unsupported
+
,-
this packaging is because:it.begin()+5
the efficiency like this is too low, C++ does not support
The iterator of the list does not support the one in the vector it.begin()+5
, if written like this, an error will be reported
Only supports ++
,--
void test2()
{
list<int> lt{
1,2,3,4,5,6 };
lt.begin()--;
lt.begin()++;
}
If you want to move list
the iterator to multiple positions like vector
in , you can only do this:it.begin()+5
void test2()
{
list<int> lt{
1,2,3,4,5,6 };
list<int>::iterator it = lt.begin();
for (size_t i = 0; i < 5; i++)
{
++it;
}
}
For the rest, list
the iterator also supports the previous functions, and the usage is the same
Capacity related
empty
bool empty() const;
Determine whether the container is empty
size
size_type size() const;
Returns the number of elements in the container
insert delete
list
As a two-way circular linked list, the efficiency of head insertion, head deletion, tail insertion, and tail deletion is very high, so these operations are supported in the list
function | illustrate |
---|---|
void push_front (const value_type& val); | Insert an element with value val before the first element of the list |
void pop_front(); | delete the first element in the list |
void push_back (const value_type& val); | Insert an element with value val at the end of the list |
void pop_back(); | delete the last element in the list |
void test3()
{
list<int> lt{
1,2,3,4,5,6 };
lt.push_back(10);
lt.push_front(0);
lt.pop_back();
lt.pop_front();
}
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);
insert
The operation vector
is the same as that used in , but this insert
will not cause the iterator to fail
because the insertion of the linked list must be expanded. If the iterator points to a certain node, the iterator still points to the original node after insertion, which will not lead to failure
erase
iterator erase (iterator position);
iterator erase (iterator first, iterator last);
erase
The operation vector
is the same as that in , which erase
will cause the iterator to be invalid.
The iterator points to a certain node. After deleting this node, the iterator becomes invalid.
Element operations
reverse
void reverse();
This reverse
is list
a function that comes with the class, and its function is to reverse the linked list
There <algorithm>
is also a reverse
function
reverse
in which the iterator type is a bidirectional iterator, and the iterator type of list is a bidirectional iterator, so list can also be used <algorithm>
inreverse
void test4()
{
list<int> lt{
1,2,3,4,5,6 };
lt.reverse();
reverse(lt.begin(), lt.end());
}
sort
void sort();
<algorithm>
The function is sorting, and there are also functions in the bottom layer of merging sort
, but for lists, if you want to sort, you can only use the functions list
in the library , and there are sort
functions that cannot be used<algorithm>
sort
Because the iterator type of list is a bidirectional iterator, and the parameter iterator type of is a random iterator, so the function of list cannot <algorithm>
be used .sort
<algorithm>
sort
In fact, the meaning here sort
is not great, because compared to the low efficiency <algorithm>
of the medium ( the bottom layer of the medium uses merging, and the medium uses quick sorting), and the only meaning is: convenient, the amount of data is small, you can shoot, but the amount of data is larger If it's too big, don't use it .sort
list
sort
<algorithm>
sort
list
sort
If you want to sort, you can list
copy the data in the middle to vector
the middle, and then sort , and then copy the data to the middle vector
after sortinglist
void test5()
{
list<int> lt{
5,7,3,9,1,0,4,7,8,9,4, };
vector<int> v;
//将数据从list拷贝到vector
for (auto e : lt)
{
v.push_back(e);
}
//在vector中排序
reverse(v.begin(), v.end());
//再把数据从vector拷贝到list中
for (auto e : v)
{
lt.push_back(e);
}
}
unique
void unique();
The function is to remove duplicates, but it needs to be sorted first.
void test6()
{
list<int> lt{
2,6,5,2,2,2,2};
lt.sort();
lt.unique();// 5,6
}
remove
void remove (const value_type& val);
The function of remove is to find all the positions first val
, and then erase
drop all theval
void test6()
{
list<int> lt{
1,2,3,4,5,6,6,7,8};
//移除元素6
lt.remove(6);//1,2,3,4,5,7,8
}
splice
void splice (iterator position, list& x);
void splice (iterator position, list& x, iterator i);
void splice (iterator position, list& x, iterator first, iterator last);
The function of splice is to transfer nodes
void splice (iterator position, list& x)
,x
transfer all elements in the linked list toposition
positionvoid splice (iterator position, list& x, iterator i)
, transfer the element at positionx
in the linked list to positioni
position
void splice (iterator position, list& x, iterator first, iterator last)
,x
transfer the elements in [first,last) in the linked list toposition
the position
void test7()
{
list<int> lt1{
1,2,3,4,5,6,7 };
list<int> lt2{
0,0 };
lt2.splice(++lt2.begin(), lt1);
for (auto e : lt1)
{
cout << e << " ";
}//lt1中的元素转移空了
cout << endl;
for (auto e : lt2)
{
cout << e << " ";
}//0 1 2 3 4 5 6 7 0
cout << endl;
list<int> lt3{
1,2,3,4,5,6,7 };
list<int> lt4{
0,0 };
lt4.splice(++lt4.begin(), lt3, ++lt3.begin());
for (auto e : lt3)
{
cout << e << " ";
}//1 3 4 5 6 7
cout << endl;
for (auto e : lt4)
{
cout << e << " ";
}//0 2 0
cout << endl;
list<int> lt5{
1,2,3,4,5,6,7 };
list<int> lt6{
0,0 };
lt6.splice(++lt6.begin(), lt5,++++lt5.begin(), --lt5.end());
for (auto e : lt5)
{
cout << e << " ";
}//1 2 7
cout << endl;
for (auto e : lt6)
{
cout << e << " ";
}//0 3 4 5 6 0
cout << endl;
}