图的实验

图的BFS和DFS

用到的文件路径:

结点:C:\Users\lu\Desktop\结点.txt
边:C:\Users\lu\Desktop\边.txt

vs2015以上不能直接用fopen函数,需要改变、配置;给加上一句
_CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#define M 100
typedef struct enode//边表结点
{
	int adjvex;
	struct enode *next;
}Edgenode;
typedef struct vnode//头结点
{
	char vertex;
	Edgenode * Firstedge;
}Vertenode;
typedef struct tu//存图各顶点以及顶点数和边数
{
	Vertenode ad[M];
	int n, e;
}MP;
int vis[M];//标记数组,用来记录结点是否被访问过,0表示没有被访问过,1表示被访问;
void fun()
{
	int i = 0;
	char bar[102] = { 0 };
	printf("数据输入中,请稍后\n");
	while (i <= 50)
	{
		printf("[%-50s][%3d%%]\r", bar, i * 2);
		Sleep(60);
		bar[i++] = '*';
		bar[i] = '\0';
	}
	printf("\n数据输入完毕\n");
}
void create(MP *g, int c)//后插法建立边表结点
{
	int i;
	int a, b;
	FILE *fp;
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 10);
	printf("**********************程序说明***********************\n");
	printf("*  结点文件路径:C:\\Users\\lu\\Desktop\\结点.txt       *\n");
	printf("*    边文件路径:C:\\Users\\lu\\Desktop\\边.txt         *\n");
	printf("*****************************************************\n\n");
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
	printf("****以下为后插法建立邻接表****\n");
	Edgenode *s;//边表结点
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 3);
	printf("请输入图的结点数和边数:");
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
	scanf_s("%d%d", &g->n, &g->e);//结点数和边数
	getchar();
	fp = fopen("C:\\Users\\lu\\Desktop\\结点.txt", "r");
	fun();
	Sleep(300);
	for (i = 0; i < g->n; i++)
	{
		fscanf_s(fp, "%c", &g->ad[i].vertex,1);
		g->ad[i].Firstedge = NULL;
	}
	fclose(fp);
	fp = fopen("C:\\Users\\lu\\Desktop\\边.txt", "r");
	/*getchar();*/
	for (i = 0; i < g->e; i++)//后插法建立边表结点
	{
		fscanf_s(fp, "%d%d", &a, &b);
		s = (Edgenode*)malloc(sizeof(Edgenode));
		s->adjvex = b;
		s->next = g->ad[a].Firstedge;
		g->ad[a].Firstedge = s;
		if (c == 0)
		{
			s = (Edgenode*)malloc((sizeof(Edgenode)));
			s->adjvex = a;
			s->next = g->ad[b].Firstedge;
			g->ad[b].Firstedge = s;

		}
	}
	fclose(fp);
}
void print(MP *g)//输出邻接表
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 3);
	printf("该图的邻接表输出如下:\n");
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
	int i;
	Edgenode *p1;//边表结点类型指针,用来输出邻接表;

	for (i = 0; i < g->n; i++)
	{
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 5);
		printf("%c***>   ", g->ad[i].vertex);
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
		p1 = g->ad[i].Firstedge;
		while (p1)
		{
			if (p1->next == NULL)
			{
				printf("%d", p1->adjvex);
				p1 = p1->next;
			}
			else
			{
				printf("%d-->", p1->adjvex);
				p1 = p1->next;
			}
			
		}
		printf("\n");
	}
}
void DFS(MP *g, int i)//遍历图中的连通分量---递归实现;
{
	Edgenode *p1;//临时边表结点指针;
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 2);
	printf("%c-->", g->ad[i].vertex);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
	vis[i] = 1;
	p1 = g->ad[i].Firstedge;
	while (p1)
	{
		if (vis[p1->adjvex] == 0)
		{
			DFS(g, p1->adjvex);
		}
		p1 = p1->next;
	}
}
void DFS_1(MP *g, int i)//遍历图中每个连通分量---非递归实现
{
	Edgenode *p1;
	Edgenode *st[M];
	int top = -1;
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 11);
	printf("%c***>", g->ad[i].vertex);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
	vis[i] = 1;
	p1 = g->ad[i].Firstedge;
	while (top>-1 || p1)
	{
		if (p1)
		{
			if (vis[p1->adjvex])
			{
				p1 = p1->next;
			}
			else
			{
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 11);
				printf("%c***>", g->ad[p1->adjvex].vertex);
				vis[p1->adjvex] = 1;
				st[++top] = p1;
				p1 = g->ad[p1->adjvex].Firstedge;
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
			}	
		}
		else
		{
			if (top >-1)
			{
				p1 = st[top--];
				p1 = p1->next;
			}
		}
	}

}
void DFStu(MP *g,int c)//遍历每一个连通分量,即:遍历整个图;
{
	int i;
	for (i = 0; i < g->n; i++)
	{
		vis[i] = 0;
	}
	if (c == 0)
	{
		printf("递归DFS输出:");
		for (i = 0; i < g->n; i++)
		{
			if (vis[i] == 0)//图有几个连通分量,就执行几次递归;
			{
				DFS(g, i);
			}
		}
		printf("\n");
	}
	else if(c==1)
	{
		printf("非递归DFS输出:");
		for (i = 0; i < g->n; i++)
		{
			if (vis[i] == 0)//图有几个连通分量,就执行几次递归;
			{
				DFS_1(g, i);
			}
		}
		printf("\n");
	}
	
}
void BFS(MP *g, int i)
{
	int a;
	Edgenode *p1;
	int queue[M];//队列
	int front, rear;//队首和队尾下标
	front = rear = 0;//初始化
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 11);
	printf("%c--->", g->ad[i].vertex);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
	vis[i] = 1;
	queue[rear++] = i;//将i入队列
	while (rear > front)
	{
		a = queue[front++];//取队首元素,并出队列;
		p1 = g->ad[a].Firstedge;
		while (p1)
		{
			if (vis[p1->adjvex] == 0)
			{
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 11);
				printf("%c--->", g->ad[p1->adjvex].vertex);
				queue[rear++] = p1->adjvex;
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
				vis[p1->adjvex] = 1;
			}
			p1 = p1->next;
		}
	}
}
void BFStu(MP *g)
{
	int i;
	int count = 0;
	for (i = 0; i < g->n; i++)
	{
		vis[i] = 0;
	}
	for (i = 0; i < g->n; i++)
	{
		if (vis[i] == 0)
		{
			BFS(g, i);
			count++;
		}
	}
	printf("\n该图的连通分量为:%d\n", count);
}
int main()
{
	MP A;
	MP *p;
	p = &A;
	int i, j;
	create(p, 0);
	print(p);
	int c;
	printf("BFS输出结果如下:\n");
	BFStu(p);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 3);
	printf("请输入DFS类型(0表示递归or1表示非递归):");
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
	scanf_s("%d", &c);
	DFStu(p,c);
	return 0;
}

在这里插入图片描述

发布了59 篇原创文章 · 获赞 47 · 访问量 5506

猜你喜欢

转载自blog.csdn.net/qq_44755403/article/details/103259784