如何在 c++ 的类中递归调用函数方法?
How to call a function method recursively in classes in c++?
所以,不久前我开始学习和阅读OOP,我一直在使用类和对象实现我所知道的所有数据结构,只是为了整体练习和习惯在c ++中使用OOP。
我正在实现树数据结构,我一直想知道如何递归调用方法(我知道我必须传入一个参数(,以便当我在 main 中创建一个对象并调用特定方法时,它写得像下面的a.inorder();
而不是a.inorder(root)
,因为 root 是一个私有属性。
这可能吗?
我的代码:
#include<iostream>
using namespace std;
struct node
{
int data;
node* left;
node* right;
};
class tree
{
private:
node* root;
public:
tree();
tree(int val);
void insert(int val);
void preorder();
void postorder();
void inorder();
int count();
};
tree::tree() : root { NULL }
{
}
tree::tree(int val)
{
root = new node;
root->data = val;
root->left = root->right = NULL;
}
void tree::insert(int val)
{
if (!root)
{
root = new node;
root->data = val;
root->left = root->right = NULL;
}
else
{
node* t = root;
node* p = NULL;
while (t)
{
p = t;
if (val > root->data)
t = root->right;
else
t = root->left;
}
t = new node;
t->data = val;
t->left = t->right = NULL;
if (p->data > t->data)
p->left = t;
else
p->right = t;
}
}
void tree::preorder()
{
if (root)
{
}
}
在你的设计中,node
指的是它自己。由于递归对象node
,因此您可以在node
上定义递归方法:
struct node
{
int data;
node* left;
node* right;
void preorder() {
//...
left->preorder();
right->preorder();
}
};
然后,tree::preorder()
只会向root->preorder()
发出一个电话。
编写一个私有静态递归函数,将指向根节点的指针传递给它,并从相应的公共非静态成员函数调用该函数。
例如
public:
std::ostream & preorder( std::ostream &os = std::cout ) const
{
return preorder( root, os );
}
//...
private:
static std::ostream & preorder( const node *root, std::ostream &os );
//...
这是一个评论而不是实际的答案,因为它解决的问题与您询问的问题不同。但是,对于评论空间来说太长了,这就是我在这里发布它的原因。
我想你在这一部分中错误地提到了root
while (t)
{
p = t;
if (val > root->data)
t = root->right;
else
t = root->left;
}
恕我直言,它应该看起来像这样:
while (t)
{
p = t;
if (val > t->data)
t = t->right;
else
t = t->left;
}
此外,将要查找插入位置的代码与进行实际插入的代码进行比较:
if (p->data > t->data)
p->left = t;
else
p->right = t;
您以相反的顺序放置了一个比较子表达式 - 在查找时,您测试新值是否大于现有节点中的值,但在插入时,您测试现有值是否大于新值。如果它们不同,代码将正常工作,因为您还交换了"then"和"else"分支中的left
和right
。
但是,如果值看起来相等,则执行控件将在两个位置转到"else"。因此,测试代码可能会在空指针left
停止,但随后会将一个新节点附加到right
,该节点未被测试为NULL
。
为什么tree
类会对node
进行内部操作?node
类最了解node
的内部结构,所以让它自己初始化。这也将帮助您坚持 DRY 原则,间接坚持 KISS 原则以及单一责任原则。
结构节点 { 整数数据; 节点* 左; 节点* 右; node(int val( : data(val(, left(NULL(, right(NULL( {} }; 类树 { 私人: 节点* 根; 公共: 树((; 树(int val(; 空隙插入(int val(; }; 树::树(( : 根 { 空 } { } 树::树(int val( : 根(new node(val(( { } 空树::插入(整数值( { 如果(!根( { 根 = 新节点(val(; } 还 { 节点* t = 根; 节点* p = 空; 而 (t( { p = t; 如果(数据( t = t->左; 还 t = t->右; } t = 新节点(val(; 如果(t->数据 数据( p->左 = t; 还 p->右 = t; } }
此外,您也可以使insert
递归。
结构节点 { 整数数据; 节点* 左; 节点* 右; node(int val( : data(val(, left(NULL(, right(NULL( {} }; 类树 { 私人: 节点* 根; 公共: 树((; 树(int val(; 空隙插入(int val(; 保护: void insertat(node* p, int val(; }; 空树::插入(整数值( { 如果(!根( 根 = 新节点(val(; 还 插入(根,瓦尔(; } void tree::insertat(node* t, int val(; { 如果(数据( { 如果(T->左( 插入(T->左,瓦尔(; 还 t->left = new node(val(; } 还 { 如果(T->右( 插入(t->右,瓦尔(; 还 t->right = new node(val(; } }
- 如何在Elixir中调用递归函数并行
- 返回递归调用和仅递归调用的区别
- 使用静态变量的递归调用的不同输出
- 即使没有调用这个递归函数,它是如何工作的?
- 在对象指针上调用 Delete 是否会递归删除其动态分配的成员
- 复制构造函数中的递归调用
- 为什么编译器将其解析为函数指针而不是递归调用?
- 如何在 c++ 的类中递归调用函数方法?
- 如何在递归函数调用中返回当前函数值
- 了解使用堆栈实现队列的递归调用机制
- 递归函数调用在后台工作
- 如何通过函数指针递归调用类成员函数?
- 条件加倍时的递归调用
- 对可变参数函数的递归调用的链接器错误
- 在循环中调用递归函数
- ambigus调用递归sudoku_backtracker函数
- 如何在C++中调用递归链表遍历函数
- 为什么在NULL检查之后要在指针上调用递归函数?
- 通过结构调用递归函数
- 如果在指令之前调用递归函数怎么办