Detailed Explanation of C++List Class

Table of contents

1. List introduction

2. Common use of List

  2.1 The constructor of list

  2.2 Use of list iterators

  2.3 list capacity

  2.4 list element access

  2.5 list modifiers

  2.6 The iterator of the list is invalid

3. The simulation implementation of List

  3.1 list simulation implementation (skipable)

  3.2 Reverse iterator implementation

        3.2.1 list reverse iterator

        3.2.2 vector reverse iterator

4. Comparison of List and Vector


1. List introduction

  1. list is a sequential container that can be inserted and deleted at any position within a constant range, and the container can be iterated back and forth.
  2. The bottom layer of the list is a doubly linked list structure. Each element in the doubly linked list is stored in an independent node that is not related to each other, and the pointer points to the previous element and the next element in the node.
  3. list is very similar to forward_list: the main difference is that forward_list is a singly linked list that can only be iterated forward, which makes it simpler and more efficient .
  4. Compared with other serial containers (array, vector, deque), list usually has better execution efficiency for inserting and removing elements at any position.
  5. Compared with other sequential containers, the biggest defect of list and forward_list is that it does not support random access at any position. For example, to access the sixth element of the list, you must iterate from a known position (such as the head or tail) to the position over which iterating requires linear time overhead; the list also requires some additional space to hold the associated information for each node (this can be an important factor for large lists storing elements of smaller types ).

2. Common use of List

  2.1 The constructor of list

Constructor (construct) Interface Description
list (size_type n, const value_type& val = value_type())
The constructed list contains n elements whose value is val
list()
Construct an empty list
list (const list& x)
copy constructor
list (InputIterator fifirst, InputIterator last)
Constructs a list with elements in the range [first, last)

  2.2 Use of list iterators

function declaration Interface Description
begin+end
Returns an iterator to the first element + returns an iterator to the next position of the last element
rbegin+rend
Return the reverse_iterator of the first element , that is, the end position + return the reverse_iterator of the next position of the last element , that is, the begin position

end is the next position of the last node, begin is the position of the first node

【Notice】
  • begin and end are forward iterators, perform ++ operations on the iterator, and the iterator moves backward
  • rbegin(end) and rend(begin) are reverse iterators, perform ++ operations on the iterator, and the iterator moves forward

 Simple test:

void test3()
{
	list<int>lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	list<int>::iterator it = lt.begin();
	while (it != lt.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	//反向迭代器
	list<int>::reverse_iterator rit = lt.rbegin();
	while (rit != lt.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;
}

  2.3 list capacity

function declaration Interface Description
empty Check whether the list is empty, return true, otherwise return false
size Returns the number of valid nodes in the list

  2.4 list element access

function declaration Interface Description
front Returns a reference to the value in the first node of the list
back Returns a reference to the value in the last node of the list

  2.5 list modifiers

function declaration Interface Description
push_front Insert an element with value val before the first element of the list
pop_front delete the first element in the list
push_back

Insert an element with value val at the end of the list

pop_back delete the last element in the list
insert Insert an element with value val at position pos
erase Delete the element at position pos
swap Swap the elements of two lists
clear Clear the valid elements in the list

  2.6 The iterator of the list is invalid

Iterator invalidation: that is, the node pointed to by the iterator is invalid, that is, the node is deleted.
  • The list will only become invalid after the delete operation

 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 .

Use the same as vector, accepting iterator return value.

void test4()
{
	int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
	list<int> l(array, array + sizeof(array) / sizeof(array[0]));
	auto it = l.begin();
	//while (it != l.end())
	//{
	//	// erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给其赋值
	//		l.erase(it);
	//	++it;
	//}
	//改正
	while (it != l.end())
	{
		// erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给其赋值
		it=l.erase(it);
		++it;
	}
}

3. The simulation implementation of List

  3.1 list simulation implementation (skipable)

Node structure:

 Iterator structure:

What is stored in the pointer is the address pointing to the data, -> (because the pointer has the address pointing to the data, it can directly point to the data, so it needs to return the address pointing to the data). p->a is equivalent to (*p).a

//T* operator->()
Ptr operator->()
{
    return &(operator*());
}

Linked list structure:

Private member variables:

	private:
		Node* _head;

 Constructor:

 Copy constructor:

Assignment operator overloading:

Destructor:

iterators:

insert:

erase:

 push_back和pop_back:

push_front和pop_front:

  3.2 Reverse iterator implementation

Iterator classification: (functional perspective) one-way, two-way, random.

Random iterators are special one-way and two-way iterators (inheritance relationship)

Reverse iterators: (symmetric) forward iterator adaptations generate adaptations that support containers that can be ++,--.
That is: the reverse iterator can contain a forward iterator inside, just wrap the interface of the forward iterator.

        3.2.1 list reverse iterator

        3.2.2 vector reverse iterator

4. Comparison of List and Vector

Both vector and list are very important sequential containers in STL. Due to the different underlying structures of the two containers, their characteristics and application scenarios are different. The main differences are as follows:
vector
list
underlying structure
Dynamic sequence table, a continuous space
Doubly linked circular list with head node
random access
Support random access, the efficiency of accessing an element is O(1)
Random access is not supported, and the efficiency of accessing an element is O(N)
insert and delete
Insertion and deletion at any position is inefficient, and elements need to be moved. The time complexity is O(N) . When inserting, it may need to increase capacity. Increase: open up new space , copy elements, and release old space, resulting in lower efficiency
Insertion and deletion at any position are highly efficient, do not need to move elements, and the time complexity is O(1)
space utilization
The bottom layer is a continuous space, which is not easy to cause memory fragmentation, high space utilization rate, and high cache utilization rate
The underlying nodes are dynamically opened, and small nodes are likely to cause memory fragmentation, low space utilization, and low cache utilization
iterator _
Original ecological pointer
Encapsulate the original ecological pointer ( node ​​pointer )
iterator invalidation _
When inserting elements, all iterators must be reassigned, because inserting elements may cause re-expansion, causing the original iterator to become invalid. When deleting , the current iterator needs to be reassigned or it will become invalid
Inserting an element will not invalidate the iterator. When deleting an element, only the current iterator will be invalidated, and other iterators will not be affected
usage scenario
Requires efficient storage, supports random access, and does not care about insertion and deletion efficiency
Lots of insert and delete operations, don't care about random access

Guess you like

Origin blog.csdn.net/bang___bang_/article/details/130547822