📅  最后修改于: 2023-12-03 14:39:58.585000             🧑  作者: Mango
正向列表(forward list)和双向列表(double linked list)都是一种常见的数据结构,用来保存一系列元素。它们的主要区别在于元素之间的链接方式:正向列表的元素只能向后链接,而双向列表的元素不仅可以向后链接,还可以向前链接。
正向列表的元素结构非常简单,每个元素(节点)只需要包含一个指向下一个元素的指针即可:
template <typename T>
struct node {
T data;
node<T> *next;
};
双向列表的元素稍微复杂一些,因为每个元素既要包含一个指向下一个元素的指针,还要包含一个指向前一个元素的指针:
template <typename T>
struct node {
T data;
node<T> *prev;
node<T> *next;
};
正向列表的操作都非常简单,常用的操作有:
向列表中插入一个元素可以使用 push_front
或 insert
函数。push_front
函数向列表头部插入一个元素,而 insert
函数则在指定位置插入一个元素。
#include <forward_list>
std::forward_list<int> flist = {1, 2, 3};
// 在头部插入一个元素
flist.push_front(0);
// 在第二个位置插入一个元素
auto it = flist.begin(); ++it;
flist.insert_after(it, 9);
从列表中删除一个元素可以使用 remove
函数。该函数会删除列表中所有符合条件的元素,可以利用 lambda 表达式指定条件。
std::forward_list<int> flist = {1, 2, 3, 1, 2, 3};
// 删除所有的 2
flist.remove_if([](int x) { return x == 2; });
遍历一个正向列表可以使用迭代器,迭代器的操作和普通指针类似:
std::forward_list<int> flist = {1, 2, 3};
// 遍历列表并打印每个元素
for (auto it = flist.begin(); it != flist.end(); ++it) {
std::cout << *it << " ";
}
双向列表和正向列表用法类似,常用的操作有:
向列表中插入一个元素可以使用 push_front
或 push_back
函数。push_front
函数向列表头部插入一个元素,而 push_back
函数则在列表尾部插入一个元素。另外,还可以使用 insert
函数在列表中指定位置插入元素。
#include <list>
std::list<int> list = {1, 2, 3};
// 在头部插入一个元素
list.push_front(0);
// 在尾部插入一个元素
list.push_back(4);
// 在第二个位置插入一个元素
auto it = list.begin(); ++it;
list.insert(it, 9);
从列表中删除一个元素可以使用 remove
函数。该函数会删除列表中所有符合条件的元素,可以利用 lambda 表达式指定条件。
还可以使用 pop_front
和 pop_back
函数分别删除列表头和列表尾的元素。
std::list<int> list = {4, 3, 2, 1, 0};
// 删除所有的奇数
list.remove_if([](int x) { return x % 2 == 1; });
// 删除列表头尾的元素
list.pop_front();
list.pop_back();
遍历一个双向列表同样可以使用迭代器,和正向列表不同的是,双向列表的迭代器既可以向前移动,也可以向后移动。
std::list<int> list = {1, 2, 3};
// 遍历列表并打印每个元素
for (auto it = list.begin(); it != list.end(); ++it) {
std::cout << *it << " ";
}