Figure 11 - determine if the figure is a tree

Write algorithm to judge whether an undirected graph is a tree.

[analysis]
The condition for a undirected graph G to be a tree is: G must be a connected graph without a loop or a connected graph with n-1 edges. Here we use the latter as the judging condition. For example, the following figure shows:

The undirected graph above is a tree with six vertices and five edges.

code:

#include<stdlib.h>
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<iostream>
using namespace std;
/*Adjacency table type definition of Graphs*/
typedef char VertexType[4];
typedef char InfoPtr;
typedef int VRType;
#define MAXSIZE 100 / * maximum number of vertices*/
typedef enum { DG, DN, UG, UN }GraphKind; 	/*Types of graphs: directed graph, directed net, undirected graph and undirected net*/
typedef struct ArcNode			/*Type definition of edge node*/
{
	int adjvex; 				/*The position of the vertex pointed by the arc*/
	InfoPtr *info;				/*Arc related information*/
	struct ArcNode *nextarc; 	/*Indicates the next vertex adjacent to that vertex*/
}ArcNode;
typedef struct VNode			/*Type definition of head node*/
{
	VertexType data; 			/*Used to store vertices*/
	ArcNode *firstarc; 			/*Indicates the first vertex adjacent to the vertex*/
}VNode, AdjList[MAXSIZE];
typedef struct					/*Type definition of graph*/
{
	AdjList vertex;
	int vexnum, arcnum;			/*The number of vertices and arcs in a graph*/
	GraphKind kind; 			/*Types of Graphs*/
}AdjGraph;
int LocateVertex(AdjGraph G, VertexType v);
void CreateGraph(AdjGraph *G);
void DisplayGraph(AdjGraph G);
void DestroyGraph(AdjGraph *G);
void DFS(AdjGraph *G, int v, int *vNum, int *eNum, int visited[]);
int LocateVertex(AdjGraph G, VertexType v)
//Return to the corresponding position of vertices in the graph
{
	int i;
	for (i = 0; i < G.vexnum; i++)
		if (strcmp(G.vertex[i].data, v) == 0)
			return i;
	return -1;
}
void CreateGraph(AdjGraph *G)
//Using adjacency table storage structure to create undirected graph G
{
	int i, j, k;
	VertexType v1, v2;		//Define two vertices v1 and v2
	ArcNode *p;
	cout << "Please enter the number of vertices and edges of the graph: ";
	cin >> (*G).vexnum >> (*G).arcnum;
	cout << "Please input" << G->vexnum << "Value of vertices:" << endl;
	for (i = 0; i < G->vexnum; i++)	//Store vertex in head node
	{
		cin >> G->vertex[i].data;
		G->vertex[i].firstarc = NULL;	//Leave associated vertices empty
	}
	cout << "Please input the end of arc head:" << endl;
	for (k = 0; k < G->arcnum; k++)	//Set up side chain list
	{
		cin >> v1 >> v2;
		i = LocateVertex(*G, v1);/*Determine the number corresponding to v1*/
		j = LocateVertex(*G, v2);/*Determine the number corresponding to v2*/
								 //j creates an adjacency table for arc head i and arc tail
		p = (ArcNode*)malloc(sizeof(ArcNode));
		p->adjvex = j;
		p->info = NULL;
		p->nextarc = G->vertex[i].firstarc;
		G->vertex[i].firstarc = p;
		//i creates an adjacency table for arc head j and arc tail
		p = (ArcNode*)malloc(sizeof(ArcNode));
		p->adjvex = i;
		p->info = NULL;
		p->nextarc = G->vertex[j].firstarc;
		G->vertex[j].firstarc = p;
	}
	(*G).kind = UG;
}
void DestroyGraph(AdjGraph *G)
//Destroy undirected graph G
{
	int i;
	ArcNode *p, *q;
	for (i = 0; i < (*G).vexnum; i++)	//Release edge table node in graph
	{
		p = G->vertex[i].firstarc;//p points to the first node of the edge table
		if (p != NULL)			//If the edge table is not empty, the nodes of the edge table are released
		{
			q = p->nextarc;
			free(p);
			p = q;
		}
	}
	(*G).vexnum = 0;		//Set the number of vertices to 0
	(*G).arcnum = 0;		//Set the number of sides to 0
}
void DisplayGraph(AdjGraph G)
//Adjacency matrix G of output graph
{
	int i;
	ArcNode *p;
	cout << G.vexnum << "Apex:" << endl;
	for (i = 0; i < G.vexnum; i++)
		cout << G.vertex[i].data << " ";
	cout << endl << G.arcnum << "Strip edge:" << endl;
	for (i = 0; i < G.vexnum; i++)
	{
		p = G.vertex[i].firstarc;
		while (p)
		{
			cout << G.vertex[i].data << "→" << G.vertex[p->adjvex].data << " ";
			p = p->nextarc;
		}
		cout << endl;
	}
}
int IsTree(AdjGraph *G)
{
	int vNum = 0, eNum = 0, i, visited[MAXSIZE];
	for (i = 0; i < G->vexnum; i++)
		visited[i] = 0;
	DFS(G, 0, &vNum, &eNum, visited);
	if (vNum == G->vexnum && eNum == 2 * (G->vexnum - 1))
		return 1;
	else
		return 0;
}
void DFS(AdjGraph *G, int v, int *vNum, int *eNum, int visited[])
{
	ArcNode *p;
	visited[v] = 1;
	(*vNum)++;
	p = G->vertex[v].firstarc;
	while (p != NULL)
	{
		(*eNum)++;
		if (visited[p->adjvex] == 0)
			DFS(G, p->adjvex, vNum, eNum, visited);
		p = p->nextarc;
	}
}
void main()
{
	AdjGraph G;
	cout << "Using adjacency table to create undirected graph G: " << endl;
	CreateGraph(&G);
	cout << "Output undirected graph G Adjacency table of:" << endl;
	DisplayGraph(G);
	if (IsTree(&G))
		cout << "Undirected graph G It's a tree.!" << endl;
	else
		cout << "Undirected graph G Not a tree!" << endl;
	DestroyGraph(&G);

	system("pause");
}

Result:

Use adjacency table to create undirected graph G:
Please enter the number of vertices and edges of the graph: 6 5
 Enter values for 6 vertices:
A B C D E F
 Please enter the tail arc head:
A B
A C
B E
C D
C F
 Output adjacency table of undirected graph G:
6 vertices:
A B C D E F
 The 5 side:
A→C A→B
B→E B→A
C→F C→D C→A
D→C
E→B
F→C
 Undirected graph G is a tree!

 

Posted by waradmin on Sun, 03 Nov 2019 03:53:24 -0800