WEBVTT

00:00.150 --> 00:07.470
Hello again! In this video, we are going to look at list operations. With C++ lists, we can do most of

00:07.470 --> 00:09.990
the operations that we can do on sequential containers.

00:10.530 --> 00:14.220
We can use push_back() and push_front() for adding elements to the container.

00:15.030 --> 00:19.350
We can use iterators to loop over some of the elements, or all the elements, in a list.

00:20.370 --> 00:24.540
One important difference is that lists do not support random access.

00:25.320 --> 00:26.460
With a vector or string,

00:26.460 --> 00:31.560
we can jump straight to the sixth element, for example. With a list we have to start at the beginning

00:31.860 --> 00:33.330
and iterate until we get there.

00:34.380 --> 00:40.020
So this means that the functions in the <algorithm> header, which require random access, are not supported.

00:40.560 --> 00:46.080
For example, if we try to call sort() with a list or a forward_list as argument, then that will not

00:46.080 --> 00:46.560
compile.

00:47.340 --> 00:54.300
Instead, this each member function we have to use, but that will work fine. And it is specialized to

00:54.300 --> 00:55.890
be efficient when sorting lists.

00:58.290 --> 01:02.790
Quite often, containers have member functions which have the same functionality as algorithms.

01:03.510 --> 01:09.390
In the case of list, these can sometimes be much more efficient than using the generic versions. For

01:09.390 --> 01:12.900
example, with remove(). We saw with the generic version with vector.

01:13.350 --> 01:17.610
It does not actually delete the elements from the container, it just moves them to the back

01:17.610 --> 01:25.020
of the container, and then you have to call erase(). The member function for list will actually delete the elements

01:25.020 --> 01:25.640
straightaway.

01:25.650 --> 01:30.970
So no messing around, and no call to erase(). And that just involves assigning a couple of pointers.

01:31.620 --> 01:36.210
So obviously, that is going to be much faster than calling the generic version and moving list

01:36.210 --> 01:36.690
elements arounf.

01:39.510 --> 01:44.040
So let's have a look at this remove() member function. In fact, first of all, let's check whether we

01:44.040 --> 01:45.630
can use the generic sort.

01:48.340 --> 01:51.550
And no, we get one of those horrible template errors.

01:54.220 --> 01:56.710
So let's go back to using the member function version.

01:57.430 --> 02:04.390
So here is our list. And then we are going to call remove(), using the member function.

02:04.840 --> 02:07.150
So this will remove the elements with value 3.

02:07.690 --> 02:09.010
It will delete it straightaway.

02:09.010 --> 02:10.750
So we do not need to call erase.

02:13.260 --> 02:19.350
So there is our list. There is the sorted version of the list, and there is the list after removing the

02:19.350 --> 02:20.610
element with value 3.

02:23.300 --> 02:28.910
So in general, if you're going to be moving elements around, it's much better to use the list member function

02:28.910 --> 02:30.260
than the generic algorithm.

02:30.740 --> 02:36.260
So that applies to things like reverse(), remove(), which we just saw, remove_if() and unique().

02:39.440 --> 02:43.100
There are also some functions which are specific to lists.

02:44.360 --> 02:46.340
One of these is the merge() member function.

02:46.580 --> 02:52.100
So this takes another list as argument, and it will move all the elements from that argument list into

02:52.100 --> 02:53.870
the list that it was called on.

02:55.160 --> 02:59.930
So the result is going to be the combination of all the elements in the two lists, and the second

02:59.930 --> 03:01.070
list is going to be empty.

03:01.850 --> 03:06.530
If we sort both the lists before calling this, then the result will be sorted as well.

03:09.210 --> 03:11.310
So here we have two lists.

03:13.910 --> 03:19.400
We are going to sort them, using the member function, of course, and then we call merge() on "list1".

03:19.820 --> 03:23.720
So the elements from "list2" are going to be merged into "list1".

03:24.890 --> 03:28.500
So list1 is going to contain all the elements from both the lists, and list2

03:28.500 --> 03:29.660
is going to be empty.

03:33.750 --> 03:35.430
And that is what we get.

03:36.060 --> 03:39.960
So list1 has all the elements, and list2 is empty.

03:41.880 --> 03:44.610
Another member function is splice(). This time,

03:44.670 --> 03:49.260
we give it an iterator as the first arguments, so that is an iterator into the first list.

03:50.040 --> 03:54.510
And this will insert all the elements from the second list just before that iteration.

03:54.810 --> 03:56.610
So this is for the double linked list.

03:58.650 --> 04:01.530
We will see in a minute that the forward_list works slightly differently.

04:02.490 --> 04:07.940
And you can also provide a single iterator from the second list, which will just move one element. Or

04:07.950 --> 04:12.060
you can provide an iterator range, which will move some of the elements from the second list.

04:17.090 --> 04:19.360
So we have the same two lists again.

04:21.300 --> 04:24.980
We are going to an iterator to the second element of list1.

04:25.730 --> 04:31.080
Then we are going to pass that as the first argument to splice(), and then this will insert all the elements from

04:31.090 --> 04:34.670
list2 just before the second element of list1.

04:35.480 --> 04:39.500
So we expect to see 1, 9, 3, 14, 12 and so on.

04:43.070 --> 04:48.110
And there we are, the elements from list2 have been inserted just before the second element

04:48.110 --> 04:48.890
of list1.

04:52.290 --> 04:54.600
With forward_list, it works slightly differently.

04:54.630 --> 05:00.570
You will remember that, when we inserted into a forward_list, we had to use insert_after() instead of

05:00.570 --> 05:06.330
just insert(). And that would insert the new element after the operator, instead of before it, which

05:06.330 --> 05:07.380
all the other containers do.

05:07.920 --> 05:09.500
And the same thing works with splice().

05:09.900 --> 05:13.890
splice() is really just inserting a whole list instead of a single element.

05:15.180 --> 05:22.260
So we have splice_after() instead of splice, and instead of inserting before an iterator, we insert after

05:22.260 --> 05:22.920
the iterator.

05:28.450 --> 05:31.870
So let's try this. So we have a forward_list with the same elements.

05:32.410 --> 05:36.460
And then we call splice_after(), with the an iterator to the first element of list1.

05:38.380 --> 05:40.030
And then we get the same results again.

05:40.420 --> 05:42.970
The elements are inserted after the first element.

05:43.900 --> 05:45.340
Okay, so that is it for this feature.

05:45.820 --> 05:46.630
I will see you next time.

05:46.630 --> 05:49.090
But until then, keep coding!
