我正在为excersise实现map,我正处于迭代它(完成并正在工作)的地步,但问题是我不知道如何实现最后一个元素(大概是一个空链接)。我想我会附加一些特殊的链接(基本链接的后代),然后将其附加到最后一个元素,这样我就可以检测到我是否在真正的最后一个元素。我想知道你对这个想法会有什么看法,并且可能会听到一些更传统和经常使用的技术来做这件事。
答案 0 :(得分:3)
实现end
有两种方法:虚节点和单数迭代器(即NULL)。
NULL的问题在于,如果递减--end()
,则需要能够返回结构。
GCC的作用是在map
对象本身中创建一个截断的虚拟节点。它有链接但没有数据有效负载。它作为树的根维护,具有调用特殊行为的循环父链接。在语义上它可能有点乱,但C ++兼容的语义应该值得麻烦。
答案 1 :(得分:3)
如果你的迭代器不是双向的,那么你真的不需要指向任何东西(在这种情况下只使用NULL)。 end()
只需要在双向迭代器的情况下具有实际值,因为在这种情况下,您需要能够从end()
向后移动到列表的开头。
GNU C ++库(如果将std::map
与GCC / G ++一起使用,可获得的内容)将end()
实现为指向树根节点的指针。这样,如果在双向迭代器中使用,您可以访问根节点以查找树中最右侧的节点(这是end()
之前的节点)。
编辑以解释空树
地图本身总是包含树根的节点(它不是指针,它是普通的成员节点)。当树为空时,此节点的两个叶子都指向节点本身(end()
也是如此)。因此,在空树begin()
中将返回与end()
相同的内容。
所以我们有这样的事情:
template<class T> struct node_t {
T data;
node_t *left;
node_t *right;
};
template<class T> class map {
private:
node_t root;
public:
// ...
iterator begin() { return iterator(root.left); }
iterator end() { return iterator(&root); }
}
答案 2 :(得分:0)
使用虚拟节点。