求无向图是否为一颗树,请写出c语言代码实现,图为邻接表
时间: 2024-03-25 09:39:07 浏览: 64
以下是使用深度优先搜索(DFS)来判断一张无向图是否为一棵树的C语言代码实现,其中图用邻接表来表示:
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAXN 100
typedef struct node // 邻接表中的节点
{
int adjvex; // 邻接点的编号
struct node *next; // 指向下一个邻接点的指针
}Node;
Node *G[MAXN]; // 无向图的邻接表
bool visited[MAXN]; // 记录节点是否被访问过
int n, m; // 无向图的节点数和边数
void add_edge(int u, int v) // 添加一条边
{
Node *p = (Node*)malloc(sizeof(Node));
p->adjvex = v;
p->next = G[u];
G[u] = p;
}
bool is_tree(int u, int parent)
{
visited[u] = true; // 标记节点为已访问
for (Node *p = G[u]; p != NULL; p = p->next)
{
int v = p->adjvex;
if (!visited[v]) // 如果节点v没有被访问过
{
if (is_tree(v, u) == false) // 递归判断节点v是否在以u为根的子树中出现过
{
return false;
}
}
else if (v != parent) // 如果节点v已经被访问过,且不是节点u的父节点
{
return false; // 说明出现了环,不是一棵树
}
}
return true; // 没有出现环,是一棵树
}
int main()
{
scanf("%d%d", &n, &m);
// 初始化邻接表
for (int i = 0; i < n; i++)
{
G[i] = NULL;
}
// 读入边
for (int i = 0; i < m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
add_edge(u, v); // 添加一条从u到v的边
add_edge(v, u); // 添加一条从v到u的边
}
// 判断是否是一棵树
if (is_tree(0, -1) == true && m == n - 1) // 从节点0开始遍历,-1表示没有父节点
{
printf("This is a tree.\n");
}
else
{
printf("This is not a tree.\n");
}
// 释放内存
for (int i = 0; i < n; i++)
{
Node *p = G[i];
while (p != NULL)
{
Node *tmp = p;
p = p->next;
free(tmp);
}
}
return 0;
}
```
注意,这里假设无向图的节点编号从0开始,节点数不超过100。如果节点编号从1开始,需要将数组下标减1。
阅读全文