自定义有序映射实现ceilingEntry遇语法错误,求实现示例
解决BST语法错误并实现
ceilingEntry函数 先拆解你遇到的两个问题,再给出ceilingEntry的完整实现:
问题1:嵌套模板>>语法错误
在C03标准中,嵌套模板的右尖括号必须分开写(> >),但C11及以后的标准允许直接写>>。如果修改成> >后仍然报错,大概率是**依赖名称没有加typename**导致的——比如在SearchTree中引用LinkedBinaryTree<E>::Position这类依赖模板参数的类型时,必须用typename关键字明确告诉编译器这是一个类型。
问题2:BSTIterator未定义类型
这个错误应该是你在声明ceilingEntry时,没有正确引用SearchTree内部的Iterator类型。因为Iterator是依赖于模板参数E的嵌套类型,需要写成typename SearchTree<E>::Iterator(类外部),或者在SearchTree类内部直接用Iterator(类作用域内)。另外也可能是你误将SearchTree::Iterator写成了BSTIterator,检查一下函数声明的拼写即可。
修正后的代码及ceilingEntry实现
下面是添加了ceilingEntry函数的完整BST.h,同时修复了潜在的语法问题:
#include "BT.h" template<typename K, typename V> class Entry{ public: typedef K Key; typedef V Value; public: Entry(const K& k = K(), const V& v = V()) :_key(k), _value(v) {} const K& key() const {return _key;} const V& value() const {return _value;} void setKey(const K& k) {_key = k;} void setValue(const V& v){_value = v;} private: K _key; V _value; }; //Search Tree template <typename E> class SearchTree{ public: typedef typename E::Key K; typedef typename E::Value V; typedef LinkedBinaryTree<E> BinaryTree; typedef typename LinkedBinaryTree<E>::Position TPos; public: class Iterator{ public: TPos v; public: Iterator(const TPos& vv) : v(vv) {} const E& operator*() const {return *v;} E& operator*() {return *v;} bool operator==(const Iterator& p) const {return v == p.v;} bool operator!=(const Iterator& p) const {return !(v == p.v);} // 添加!=运算符方便使用 Iterator& operator++(); friend class SearchTree; }; public: SearchTree(); int getSize() const ; bool isEmpty() const ; Iterator find(const K& k); Iterator insert(const K& k, const V& x); void erase(const K& k); void erase(const Iterator& p); Iterator begin(); Iterator end(); TPos root() const; TPos finder(const K& k, const TPos& v); TPos inserter(const K& k, const V& x); TPos eraser(TPos& v); TPos restructure(const TPos& v); // 新增ceilingEntry函数 Iterator ceilingEntry(const K& k); private: // 辅助函数:递归查找ceiling节点 TPos ceilingHelper(const K& k, const TPos& current, TPos& candidate); BinaryTree T; int n; }; template <typename E> int SearchTree<E>::getSize() const {return n ;} template <typename E> SearchTree<E>::SearchTree() : n(0) {} // 实现ceilingEntry函数 template <typename E> typename SearchTree<E>::Iterator SearchTree<E>::ceilingEntry(const K& k) { if (isEmpty()) { return end(); } TPos candidate; TPos result = ceilingHelper(k, root(), candidate); // 如果找到有效节点,返回迭代器;否则返回end() return (result.isInternal()) ? Iterator(result) : end(); } // 递归辅助函数 template <typename E> typename SearchTree<E>::TPos SearchTree<E>::ceilingHelper(const K& k, const TPos& current, TPos& candidate) { if (current.isExternal()) { return candidate; } const K& currentKey = (*current).key(); if (currentKey == k) { // 找到等于k的节点,直接返回 return current; } else if (currentKey < k) { // 当前节点键小于k,去右子树找更大的 return ceilingHelper(k, current.right(), candidate); } else { // 当前节点键大于k,记录为候选,去左子树找更小的符合条件的节点 candidate = current; return ceilingHelper(k, current.left(), candidate); } } // 补充operator++的实现(原代码缺失,否则无法使用迭代器) template <typename E> typename SearchTree<E>::Iterator& SearchTree<E>::Iterator::operator++() { TPos current = v; if (current.right().isInternal()) { // 右子树存在,找右子树的最左节点 current = current.right(); while (current.left().isInternal()) { current = current.left(); } } else { // 没有右子树,向上找第一个是左孩子的父节点 TPos parent = current.parent(); while (parent.isInternal() && current == parent.right()) { current = parent; parent = parent.parent(); } current = parent; } v = current; return *this; } // 补充begin和end的实现 template <typename E> typename SearchTree<E>::Iterator SearchTree<E>::begin() { if (isEmpty()) return end(); TPos current = root(); while (current.left().isInternal()) { current = current.left(); } return Iterator(current); } template <typename E> typename SearchTree<E>::Iterator SearchTree<E>::end() { return Iterator(TPos()); // 返回空Position的迭代器作为end标记 }
关键说明
语法错误修复:
- 所有依赖模板参数的嵌套类型都添加了
typename关键字(比如typename LinkedBinaryTree<E>::Position)。 - 若使用C03,把所有
>>改成> >;C11+版本直接保留>>即可。
- 所有依赖模板参数的嵌套类型都添加了
ceilingEntry逻辑:
- 递归遍历BST:当当前节点键大于k时,记录为候选,再去左子树寻找更小的符合条件的节点;当当前节点键小于k时,去右子树寻找更大的节点;找到等于k的节点直接返回。
- 树为空或无匹配节点时,返回
end()迭代器。
补充迭代器必要实现:原代码缺失
operator++、begin()、end()的实现,这些是迭代器正常工作的基础,因此一起补充完成。
内容的提问来源于stack exchange,提问作者Arn
相关产品推荐
相关产品推荐

