Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在c++;? P>所以,我开始学习和阅读OOP很久以前,我一直在使用所有的类和对象来实现我所知道的数据结构,只是为了全面的实践,并且在C++中使用OOP变得很舒服。_C++_Oop - Fatal编程技术网

如何在c++;? P>所以,我开始学习和阅读OOP很久以前,我一直在使用所有的类和对象来实现我所知道的数据结构,只是为了全面的实践,并且在C++中使用OOP变得很舒服。

如何在c++;? P>所以,我开始学习和阅读OOP很久以前,我一直在使用所有的类和对象来实现我所知道的数据结构,只是为了全面的实践,并且在C++中使用OOP变得很舒服。,c++,oop,C++,Oop,我正在实现树数据结构,我一直想知道如何递归调用一个方法(我知道我必须传入一个参数),这样当我在main中创建一个对象并调用一个特定的方法时,它的编写方式如下a.inoorder()数据=val; 根->左=根->右=空; } 无效树::插入(int-val) { 如果(!root) { 根=新节点; 根->数据=val; 根->左=根->右=空; } 其他的 { node*t=根; node*p=NULL; while(t) { p=t; 如果(val>root->data) t=根->右; 其

我正在实现树数据结构,我一直想知道如何递归调用一个方法(我知道我必须传入一个参数),这样当我在main中创建一个对象并调用一个特定的方法时,它的编写方式如下
a.inoorder()a.inoder(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)
    {

    }
}
#包括
使用名称空间std;
结构节点
{
int数据;
节点*左;
节点*右;
};
类树
{
私人:
节点*根;
公众:
树();
树(int-val);
无效插入(int val);
无效前序();
无效邮购();
无效顺序();
int count();
};
tree::tree():根{NULL}
{
}
树::树(int-val)
{
根=新节点;
根->数据=val;
根->左=根->右=空;
}
无效树::插入(int-val)
{
如果(!root)
{
根=新节点;
根->数据=val;
根->左=根->右=空;
}
其他的
{
node*t=根;
node*p=NULL;
while(t)
{
p=t;
如果(val>root->data)
t=根->右;
其他的
t=根->左;
}
t=新节点;
t->data=val;
t->left=t->right=NULL;
如果(p->data>t->data)
p->left=t;
其他的
p->right=t;
}
}
空树::预订单()
{
如果(根)
{
}
}

编写一个私有静态递归函数,将指向根节点的指针传递给它,并从相应的公共非静态成员函数调用该函数

比如说

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 );
    //...

在您的设计中,
节点
引用自身。由于是递归的
节点
对象,因此可以在
节点
上定义递归方法:

struct node
{
    int data;
    node* left;
    node* right;

    void preorder() {
        //...
        left->preorder();
        right->preorder();
    }
};

然后,
tree::preorder()
将只发送一个调用到
root->preorder()

这是一个注释,而不是实际的答案,因为它解决的问题与您所问的不同。然而,它对于评论空间来说太长了,这就是为什么我在这里发布它

我想您在这部分中错误地引用了
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”。因此,测试代码可能会在空的
指针处停止,但随后一个新节点将附加到
,该节点未被测试为

为什么
类会对
节点
执行内部操作?
节点
类最了解
节点
的内部结构,所以让它自己初始化。这也将帮助您坚持,间接地,坚持,以及


⟼请记住,保持代码尽可能有条理是非常重要的,尤其是在学习和询问有关堆栈溢出的问题时。有助于传达结构,更重要的是,有助于我们快速找到问题的根源,而无需花费大量时间试图解码正在发生的事情。如果类具有类似
root
的属性,则将其传递给函数是多余的,则类已经知道这是什么。对于递归,您可以始终使用一个单独的
受保护的
方法进行挖掘,然后根据需要使用该方法。间接寻址是您的朋友。。。从该方法调用另一个进行递归的[private]方法“我知道我必须传入一个参数”——在类中,每个(非静态)方法属性都会自动传递一个“this”指针。在一些递归工作中,隐藏指针就足够了。
struct node
{
    int data;
    node* left;
    node* right;

    node(int val) : data(val), left(NULL), right(NULL) {}        
};

class tree
{
private:
    node* root;
public:
    tree();
    tree(int val);

    void insert(int val);
};

tree::tree() : root { NULL }
{
}

tree::tree(int val) : root(new node(val))
{
}

void tree::insert(int val)
{
    if (!root)
    {
        root = new node(val);
    }
    else
    {
        node* t = root;
        node* p = NULL;
        
        while (t)
        {
            p = t;
            
            if (val < t->data)
                t = t->left;
            else
                t = t->right;
        }
        
        t = new node(val);
        
        if (t->data < p->data)
            p->left = t;
        else
            p->right = t;
    }
}
struct node
{
    int data;
    node* left;
    node* right;

    node(int val) : data(val), left(NULL), right(NULL) {}        
};

class tree
{
private:
    node* root;
public:
    tree();
    tree(int val);

    void insert(int val);
protected:
    void insertat(node* p, int val);
};

void tree::insert(int val)
{
    if (!root)
        root = new node(val);
    else
        insertat(root, val);
}

void tree::insertat(node* t, int val);
{
    if (val < t->data)
    {
        if (t->left)
            insertat(t->left, val);
        else
            t->left = new node(val);
    }
    else
    {
        if (t->right)
            insertat(t->right, val);
        else
            t->right = new node(val);
    }
}