📜  C++中的正向列表和对列表以及示例(1)

📅  最后修改于: 2023-12-03 14:39:58.585000             🧑  作者: Mango

C++中的正向列表和双向列表

什么是正向列表和双向列表

正向列表(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_frontinsert 函数。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_frontpush_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_frontpop_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 << " ";
}