STL中list为双向链表结构, 可以实现O(1)的插入删除操作, 但是无法随机存取.
-
首先需要明确的是, list是一个双向循环链表, 链表中存在迭代器为end()的节点, 如下图所示.
distance(iter a, iter b) 可以计算两个迭代器之间的距离, 当模板类型为可随机存取类型, 如vector等, 计算方法为迭代器的减操作符;当模板类型为不可随机存取类型时, 如list, 计算方法为使 a 不断自增, 直到等于b, 返回自增的次数. cppreference 描述为:
If it is a random-access iterator, the function uses operator- to calculate this. Otherwise, the function uses the increase operator (operator++) repeatedly.下面的例子说明了list中的distance()计算.
#include <list>
#include <iostream>
using namespace tsd;
int main(){
// 列表长度为6
list<int> l({0, 1, 2, 3, 4, 5});
cout << distance(l.begin(), l.end()) << endl; // 输出6
cout << distance(l.end(), l.begin()) << endl; // 输出1
return 0;
}
- 如果想要取到固定位置的元素, 可以通过迭代器来实现, 配套使用advance与distance函数. 接上面的代码
int main(){
// 列表长度为6
list<int> l({ 0, 1, 2, 3, 4, 5 });
list<int>::iterator it = l.begin();
// 取倒数第二位, it 指向4
advance(it, distance(it, l.end()) - 2);
// 现在 it 指向4, 改为指向1
advance(it, -(distance(l.begin(), it) - 1));
cout << *it << endl;
}