C++ 哪些数据结构可以实现双叶型树?

C++ 哪些数据结构可以实现双叶型树?,c++,stl,genetic-programming,C++,Stl,Genetic Programming,Hi哪些数据结构是最好的,并且更容易实现具有两个叶类型的树,例如包含int的叶和包含函数指针的叶。我需要这个基因编程 我自己做这件事,但恐怕这是个坏主意 node.h #ifndef NODE_H #define NODE_H #include <iostream> #include <stdio.h> typedef int(* func) (int, int); using namespace std; class node { private: no

Hi哪些数据结构是最好的,并且更容易实现具有两个叶类型的树,例如包含int的叶和包含函数指针的叶。我需要这个基因编程

我自己做这件事,但恐怕这是个坏主意

node.h

#ifndef NODE_H
#define NODE_H

#include <iostream>
#include <stdio.h>

typedef int(* func) (int, int);

using namespace std;

class node
{
private:
    node * left, * right, *parent;
    int i;
    int type; //0 - term, 1 - func

public:
    node(node* parent,node* left,node* right, int i, int type);
    ~node();

    void changeLeft(node* left);
    void changeRight(node* right);
    void changeParent(node* parent);
    node* getLeft();
    node* getRight();
    node* getParent();
    int getI();

    virtual func getFunction(){return 0;}
    virtual int getTerminal(){return 1;}

    void show();
};

#endif // NODE_H
\ifndef节点
#定义节点
#包括
#包括
typedef int(*func)(int,int);
使用名称空间std;
类节点
{
私人:
节点*左、*右、*父节点;
int i;
int-type;//0-term,1-func
公众:
节点(节点*父节点、节点*左节点、节点*右节点、整数i、整数类型);
~node();
void changeLeft(节点*左侧);
作废变更权(节点*权);
作废变更父节点(节点*父节点);
节点*getLeft();
节点*getRight();
node*getParent();
int getI();
虚拟函数getFunction(){return 0;}
虚拟int getTerminal(){return 1;}
void show();
};
#endif//NODE_H

#ifndef TREE_H
#define TREE_H

#include <vector>
#include <cstdio>
#include <iostream>

#include "node.h"
#include "nodefunc.h"
#include "nodeterm.h"
#include "functionset.h"
#include "terminalset.h"

using namespace std;

enum typeInit
{
    GROW_INIT,
    FULL_INIT
};

enum typeNode
{
    TERMINAL_NODE,
    FUNCTION_NODE
};

class tree
{
public:
    vector <node*> nodes;
    int depth;
    int counterNodes;

private:
    node* root;
public:
    tree(int depth);
    ~tree();

public:
    void initialize(typeInit type);
    void show();
    node* getRoot();
    int run();

private:
    void initializeGrow(functionSet functions, terminalSet terminals, node* subroot, int depth);
    int initializeFull(functionSet functions, terminalSet terminals, node* subroot, int depth);
    int showSubtree(node* subtree, int depth);
    int runSubtree(node* subtree, int depth);
};

#endif // TREE_H
\ifndef TREE\u H
#定义树
#包括
#包括
#包括
#包括“node.h”
#包括“nodefunc.h”
#包括“nodeterm.h”
#包括“functionset.h”
#包括“terminalset.h”
使用名称空间std;
枚举类型初始化
{
开始成长,
完全初始化
};
枚举类型节点
{
终端节点,
功能节点
};
类树
{
公众:
向量节点;
智力深度;
int计数器节点;
私人:
节点*根;
公众:
树(int深度);
~tree();
公众:
void初始化(typeInit类型);
void show();
node*getRoot();
int run();
私人:
void initializeGrow(函数集函数、端子集端子、节点*子轨迹、int深度);
int initializefullel(函数集函数、终端集终端、节点*子程序、int深度);
int showSubtree(节点*子树,int深度);
int runSubtree(节点*子树,int深度);
};
#endif//TREE\u H

您可以使用标记的联盟进一步发展您的想法:

enum typeNode {TERMINAL_NODE, FUNCTION_NODE};

class node
{
    union
    {
      int i;
      func f;
    };

    typeNode type;

    // ...
};
一次只能使用其中一种类型,
type
字段明确指示正在使用的类型

通过这种方式,您还可以使用匿名联盟来代替匿名联盟

另一种方法是使用
符号
基类:

class symbol
{
public:
  virtual int eval(int [] = nullptr) = 0;

  // ...
};

class terminal : public symbol
{
public:
  virtual int eval(int []) override;
  {
    return i;
  }

  // ...

private:
  int i;
};

class function1 : public symbol
{
public:
  virtual int eval(int params[]) override;
  {
    return f(params[0], params[1]);
  }

  // ...

private:
  func f;
}
节点
类类似于:

class node
{
  node *left, *right, *parent;
  symbol *s;

  // ...
};

由于
函数
类是无状态的,因此需要将一些参数传递给
eval
函数。这是一个烦恼,但有助于保持遗传程序的简单其他部分(例如,构建树、树重组…)。

您可以使用标记的联合进一步发展您的想法:

enum typeNode {TERMINAL_NODE, FUNCTION_NODE};

class node
{
    union
    {
      int i;
      func f;
    };

    typeNode type;

    // ...
};
一次只能使用其中一种类型,
type
字段明确指示正在使用的类型

通过这种方式,您还可以使用匿名联盟来代替匿名联盟

另一种方法是使用
符号
基类:

class symbol
{
public:
  virtual int eval(int [] = nullptr) = 0;

  // ...
};

class terminal : public symbol
{
public:
  virtual int eval(int []) override;
  {
    return i;
  }

  // ...

private:
  int i;
};

class function1 : public symbol
{
public:
  virtual int eval(int params[]) override;
  {
    return f(params[0], params[1]);
  }

  // ...

private:
  func f;
}
节点
类类似于:

class node
{
  node *left, *right, *parent;
  symbol *s;

  // ...
};
由于
函数
类是无状态的,因此需要将一些参数传递给
eval
函数。这是一个麻烦,但有助于保持遗传程序的简单其他部分(例如构建树、树重组…。

使用三个地址码:。 这更容易使用

请看一看使用它的称为多表达式编程的线性遗传编程变体的实现:

使用三个地址码:。 这更容易使用


看看线性遗传编程变体的实现,称为多表达式编程,它使用它:

我认为这是可以的。如果你想要一棵树,你可以使用地图。。这是一个树结构,你是指叶子,还是指节点。叶是树中不连接到任何子节点的节点。你的意思是在同一棵树中,有些节点(或者叶子,如果我坚持使用你的原始单词)可能包含一个整数值,有些节点可能包含一个函数指针。或者你是说一棵树可以用来存储整数值,而另一棵树可以用来存储函数指针?你的树的应用是什么?我在您的声明中没有看到任何搜索或查找方法。对不起,您是对的。我是说节点,不是叶子@阿隆,那又怎样呢。节点*A;节点*B;A->changelft(B);删除B;我想这可能是个问题。你可以看看
Visitor
设计模式。我认为这没问题。如果你想要一棵树,你可以使用地图。。这是一个树结构,你是指叶子,还是指节点。叶是树中不连接到任何子节点的节点。你的意思是在同一棵树中,有些节点(或者叶子,如果我坚持使用你的原始单词)可能包含一个整数值,有些节点可能包含一个函数指针。或者你是说一棵树可以用来存储整数值,而另一棵树可以用来存储函数指针?你的树的应用是什么?我在您的声明中没有看到任何搜索或查找方法。对不起,您是对的。我是说节点,不是叶子@阿隆,那又怎样呢。节点*A;节点*B;A->changelft(B);删除B;我想这可能是个问题。你可以看看
Visitor
设计模式。我创建了两个子类:nodeFunc和nodeTerm,它可以工作,但我在想是否最好使用stl数据结构作为示例map。举个例子:你怎么看?@user3191398和一个自定义的树遍历是非常有效的。我不会使用基于
std::map
的表示法进行更改。也许你可以考虑像在向量中存储树一样的编码。我创建了两个子类:NoDunFoc和NoDeTrm,它是有效的,但是我在想是否更好地使用STL数据结构,例如MAP。举个例子:你怎么看?@user3191398和一个自定义的树遍历是非常有效的。我不会使用基于
std::map
的表示法进行更改。也许你可以考虑类似于在向量中存储树的编码。