给出一个二叉树的表示,其中最多可以有 n 个节点:
typedef struct node
{
int info,n;
struct node *left,*right;
}tree_node;
从二叉树构造一个无向图,该二叉树最多可以有 n 个节点。
图表表示为结构:
typedef struct
{
int n;
tree_node *nodes[];
int adjacency_m[][];
}graph;
我们可以使用 Prim , Kruskal 或 DFS 等算法从图中获取树。
问题:是否存在从二叉树创建图表的算法? 例如,如果以按顺序方式遍历二叉树,那么如何从中创建无向图?
答案 0 :(得分:5)
我对您了解有序遍历感到有点惊讶,但无法自行解决这个问题。我会给你一个基本的大纲:
我假设info
中的tree_node
成员是节点ID。
您必须执行以下操作:
1)初始化您的数据结构,即为所有adjacency_m[i][j] = 0
,i,j
,0 <= i < n
0 <= j < n
2)在您的有序遍历中,当您访问节点时:
tree_to_graph(tree_node *node) {
// add a pointer to the node
graph->nodes[node->info] = node;
if(node->left) {
// if node has a left child, , add adjecancy matrix entries for edges from node -> left, and left -> node
graph->adjacency_m[node->info][node->left->info] = 1;
graph->adjacency_m[node->left->info][node->info] = 1;
tree_to_graph(node->left);
}
if(node->right) {
// if node has a right child, add adjecancy matrix entries for edges from node -> right, and right-> node
graph->adjacency_m[node->info][node->right->info] = 1;
graph->adjacency_m[node->right->info][node->info] = 1;
tree_to_graph(node->right);
}
}
修改:正如您在评论中的讨论所看到的那样,您的问题并不是很清楚。你应该在树的抽象数学概念和用于表示它们的图形和数据结构之间进行划分。正如您所说,BFS,Kruskal和Prim可用于计算图形的生成树。正如在评论中讨论的那样,根据定义,任何树都是图形。图形通常用邻接矩阵表示,而二叉树通常用重新树结构表示。请注意,您也可以使用邻接矩阵表示具有相邻矩阵的二叉树(如果需要,您可以使用不同的邻接值(例如,1和2)对“左”和“右”子信息进行编码),以及具有这种递归的图形树状结构(虽然对于一般图形,您将不得不允许两个以上的传出边缘)。在您的问题中,您要问的是将二叉树的表示从树状递归结构转换为邻接矩阵。
答案 1 :(得分:2)
假设您已经实现了图形结构和向图形void add(int a, int b)
添加边的函数,我将以C方式解决您的问题。此外(为了简洁起见)我假设你有一个图形的静态全局变量,至少有一些节点深(我正在跳过角落的情况,对你来说更有趣)。
void tree_to_graph(tree_node *node) {
if (node->left != NULL) {
add(n, node->left->n);
tree_to_graph(node->left);
}
if (node->right != NULL) {
add(n, node->right->n);
tree_to_graph(node->right);
}
}
角落情况是图表不够深。你应该实施这个案子。 add
函数应在图表中添加a
到b
的边。您还应该添加一个向节点添加信息的函数,但我的代码应该是必要的工作最小值,为您留下有趣的部分。