如何使用 std::map 在C++中构建树结构
how to build a tree structure in C++ using std::map
我正在尝试用C++编写一种树状结构。就像每棵树一样,有树枝和叶子。分支可以包含其他分支以及叶子。现在我的实现要求每个分支和叶子具有不同的功能。举个例子。取树结构
Root
| |
Branch1 Branch2 Branch3
| | |
Leaf1 Leaf2 Branch4
现在每个叶子和分支都有一个不同的函数要执行,所以叶子1将有一个名为leaf1_func的函数,叶子2将有leaf2_func,分支4有Branch4_func。
我最初试图实现复合设计模式。但这意味着我将拥有与叶子一样多的类。但是由于我有大量的叶子和树枝,我想避免创建更多的类。我意识到这是一个不寻常的情况,但希望有人能在这方面帮助我。在不创建太多类的情况下实现此树的最佳方法是什么。
我也在使用地图 STL 容器来存储数据,我想使用这个树实现来解决 TSP 问题中的这个问题。
#include <cstdlib>
#include <iostream>
#include <map>
using namespace std;
int n=4;
int min=1, max=10;
struct graph
{
int nodes;//total no. of nodes or vertices namely cities
std::map<std::pair<int,int>, int> graphMap;//an object that links a pair of vertices
};
void directed_Graph(graph);
void directed_Graph(graph G)
{
//int n = G->nodes; //city count
int i, j;
for(i = 0; i <= n-1; i++)
{
for(j = 0; j <= n-1; j++)
{
if(i!=j)
{
G.graphMap[std::make_pair(i,j)] = (rand()%10)+1;
//cout<<G.graphMap[std::make_pair(i,j)]<<"n";
}
else
{
G.graphMap[std::make_pair(i,j)] = 0;
}
}
}
}
int main(int argc, char** argv)
{
graph g;
g.nodes = 4;
directed_Graph(g);
return 0;
}
具有相同签名的不同函数仍然具有相同的类型。即使函数完全不相关,您也可以使用树(类型擦除(void *
存储随机数据,然后在到达叶节点后类型转换回已知的实际类型。
struct node {
void (*fptr)(); // pointer to any function taking no args, no return
void *data; // pointer to anything, need to cast before using
};
void f() { std::cout << "hello"; }
void g() { std::cout << "world"; }
node a = { f, f };
node b = { g, g };
a.fptr();
static_cast< void (*)() >( b.data )();
还可以将虚拟方法与继承一起使用,并将指针指向树中的基类类型。这取决于节点到底是什么。
这些都与它进入图表的事实无关。
从您的图表外观来看,您似乎想要一个节点可以有两个以上子节点的树。 如果是这种情况,那么 STL 容器将不适合您。 它们是自平衡的二叉树。
如果你对二叉树没问题,那么有几种方法可以做到这一点。 第一种是编写函数,然后将函数指针或函子存储在树中。
#include <set>
int foo( ) {
return 5;
}
std::set< int (*)( ) > my_set;
my_set.insert( &foo );
这种方法的问题在于所有函数都必须具有相同的类型,即采用相同的参数并具有相同的返回类型。 更重要的是,虽然它们可以定义不同的行为,但它们不能保持状态,即你不能在函数指针中存储数据。
正如你提到的,第二个选项是编写类。 如果您需要改变节点的行为,那么最好的方法是定义一个接口并使用多态性。
#include <set>
#include <iostream>
struct base {
virtual void print( ) const = 0;
};
struct derived1 : public base {
void print( ) const { std::cout << "derived1" << std::endl; }
};
struct derived2 : public base {
void print( ) const { std::cout << "derived2" << std::endl; }
};
std::set< base* > my_set;
my_set.insert( new derived1( ));
my_set.insert( new derived2( ));
你没有说你是否需要强制某些行为是叶子,而其他行为是内部节点,或者是否需要以特定方式对节点进行排序,但如果你这样做,那么你可以通过创建自定义小于函数来实现这一点:
bool operator < ( base const * const b1, base const * const b2 ) {
// Figure out which is less here.
}
同样,如果你需要的东西不是二叉树,那么你就不走运了。 无论如何,你都需要编写一些代码来实现存储在每个节点中的行为,无论是函数还是类。
如果你的树深度有限,这样描述它很方便:
typedef std::map<std::string, double> action_map_t;
typedef std::map<std::string, action_map_t> objid_map_t;
typedef std::map<std::string, objid_map_t> objtype_map_t;
//....等等这里是深度== 3
objtype_map_t m_mapTooltipDuration;
m_mapTooltipDuration[objtype][objid][action] = atof(duration.c_str());
- 尝试构建"lock-free"数据结构C++
- OOP使用不同的结构与孩子一起构建建议
- 是否可以跨多个源文件构建 constexpr 数据结构?
- 在OSx:ld上使用CMake构建C++项目:找不到体系结构x86_64的符号
- 如何在 C++11 编译时构建具有递增值的整数成员的结构序列
- 有关为指向运行时确定的多个结构之一的指针构建类的建议
- 在C 中,如何将其作为成员变量构建数据结构
- cpp 中是否存在一种数据结构,可以轻松地提供一种基于已存在的实例构建新结构的方法
- 构建模板 使用矢量 c++ 的堆栈结构
- 将由结构构建的数组传递到将数据存储到文件中的函数
- cmake-一次针对多个体系结构,而无需在构建之间进行手动清理
- 从本机C++结构构建时,是否可以优化平面缓冲区序列化
- 为什么?在改变构建结构后,可执行文件的大小显著减少
- 为存档而构建的静态库,该存档不是要链接的体系结构(x86_64)
- 用静态const成员构建类层次结构
- 正在使用/配置为针对特定体系结构构建.dlib或.a文件
- 使用STL容器时,是否应该使用结构打包来构建libstdc++
- 递归类型真的是构建不连续的任意大小数据结构的唯一方法吗
- 如何使用套接字构建健壮的网络体系结构
- 为什么在Visual c++ 2008中构建结构时得到这些警告?