在我的数据结构教科书中,有一个函数(类ADT树的成员函数,基于数组),如下所示:
void preorderTraverse(void visit(ItemType&)) const // ItemType is a template
在所有示例代码文件中,未定义visit()。假设我需要自己定义visit(),函数参数中的函数是什么意思?
如果需要,preorderTraverse()函数应该是遍历其左子树和右子树的递归函数。 void visit()有助于做到这一点吗?
答案 0 :(得分:3)
您的访问功能看起来就像
void myVisit(ItemType &item)
作为参数的函数只意味着您可以传递自定义"回调"函数,在这种情况下,可能在前序遍历的每一步都被调用。
它真的很重要,它是一个无效的"功能; preorderTraverse
只是打电话给它。
答案 1 :(得分:1)
使用void visit()
的重点是在所有节点上执行某种操作,而不是简单地遍历树preorderedTraverse
,它将遍历树并执行{{1在所有节点上。
例如,如果我们的树正在控制由字符串(名称,年龄)键入的int值:visit()
,我们想模拟一个过去的一年,我们将编写一个函数:
struct PersonNode {std::string name; int age;};
我们会这样使用void myVisit(PersonNode &node) {
node.age++;
}
:
void preorderTraverse(void visit(ItemType&)) const
它将在树中的所有节点中执行myVisit中包含的操作。
更简单的例子是:
tree.predorderTraverse(myVisit);
和
void myVisit(PersonNode &node) {
std::cout << node.name << "'s age :" << node.age;
}
将打印所有节点。
答案 2 :(得分:0)
函数调用与函数不同。不要将功能视为f(x)
- 它们只是f
。
然后,您可以通过传递f
之类的参数来调用函数f(x)
。
现在语法void f(int)
给出了函数f
的签名和返回值 - 它什么都不返回,可以用一个int
调用。
在你的情况下:
void preorderTraverse(void visit(ItemType&))
visit
是一个参数。它必须是可以使用ItemType&
调用的函数,并且不返回任何内容。
preorderTraverse
将上述类型visit
的函数作为一个参数(实际上是匿名类型,但无论如何)。
所以你写道:
void my_function(ItemType& i){
std::cout << "boo!\n";
}
然后用:
调用遍历obj.preorderTraverse(my_function);
和obj
可以在其正文中使用您的my_function
,可能会在树中的每个元素上调用它。