如何找到循环列表的开头?
How to find tha't circular list's begin?
我正在尝试实现像 STL C++列表和列表迭代器。
列表中的节点定义如下:
struct Node{
Node *prev,*next;
value_type data;
};
我想重载运算符>并<:
bool list_iterator::operator>(const iterator_impl_base &rhs) const
bool list_iterator::operator<(const iterator_impl_base &rhs) const
这意味着如果我需要调用下一个到达 rhs.node,它将在>中返回 0,在
如果我需要调用 prev 才能到达 rhs.node,它会在>中返回 1,在
我使用循环列表实现列表。以下是列表类的一部分:
class List : public ordered_container {
protected:
Node* begin_;
Node* end_;
size_type size_;
public:
List::List() : end_(new Node){
begin_ = end_->prev = end_->next = end_;
size_=0;
}
}
所以,我不知道如何区分我是否只是通过了列表的begin_。有人可以帮助我吗?谢谢。
首先,用operator<
来表示"precedes"很奇怪。我知道这是一种练习,我只是不希望你认为这是正常的。
现在,循环列表将开始和结束存储在顶级容器对象中,因此节点本身无法判断它是头部还是尾迹,或者是否发生了反转。只有容器才能知道这一点。
循环列表的通常解决方案是在头部和尾部之间有一个哨兵节点。然后sentinel.next
是头部,sentinel.prev
是尾巴,你需要一些方法来标记哨兵本身(data
的魔法值或额外的标志(。然后,此哨兵节点可以替换容器对象中的两个指针(因此不会浪费任何空间(。
当您遍历列表时,它仍然是圆形的,但您可以判断您是否传递了您包裹的哨兵。
哨兵还有一个额外的好处,即您永远不必担心空列表中的 nullptrs。
顺便说一句,我觉得很奇怪,教师一直使用双向链表而不显示哨兵排列。在我继承的埃尔森的数据结构书的副本中,它有几页的描述,该书于1975年出版。故意教一个糟糕的双向链表有什么意义?
如果他们想让你自己弄清楚这一点,他们应该让你完成基本的列表操作,而不是这些奇怪的先行/成功运算符,因为基本操作实际上可以在没有哨兵的情况下工作,但随着它的添加而明显改进。
一个元素a
小于另一个元素b
您可以通过以下next
在end
之前到达b
。
一个元素a
大于另一个元素b
iffb
小于a
。
- Pybind11:将元组列表从Python传递到C++
- 从链接列表c++中删除一个项目
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- C++如何通过用户输入删除列表元素
- 读取文件的最后一行并输入到链接列表时出错
- 复制列表初始化的隐式转换的等级是多少
- LNK2038、MSVS2017 MAGMA的原因列表
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 没有为自己的结构调用列表推回方法
- 使用简单类型列表实现的指数编译时间.为什么
- 一对向量构造函数:初始值设定项列表与显式构造
- 如何找到循环列表的开头?
- 当通知迭代器参数初始化为空列表的开头时,list::insert 行为是什么?
- 如何从列表中找到以"b"开头的单词和带有 4 个符号的单词?
- C++链表将新节点添加到列表的开头
- 什么是结构开头的函数列表指针,称为 c++
- 如何在结果列表的开头插入生成的列表
- 在 protobuf 列表的开头插入项目
- 为什么数组的索引/列表不以 1 开头?
- Uncrustify:初始化列表:以逗号开头