以邻接表邻接矩阵创建图,深度优先遍历与广度优先遍历

参考其他博客,修改了一点点细节,没有过多简介,深度优先遍历和广度优先遍历过程可参考他人,附代码

修改一下,运行时有一处细节,邻接矩阵建立图时,对应输入的时字母,邻接表输入的时下标

 #include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>

//邻接矩阵:基于数组->用一个一维数组存储顶点,用一个二位数组存储边
//邻接表:基于链表->用一个一维数组或者一个链表来存储所有顶点

#define max 100
#define countless 32767
typedef enum { FALSE, TRUE }sf;
sf visit[max];

//邻接矩阵
typedef struct graph
{
	char vexs[max];//顶点
	int arcs[max][max];//邻接矩阵
	int vexnum;//顶点数
	int edgenum;//边数
}g;

//获取顶点v的下标
int location(g* node, char v)
{
	for (int i = 0; i < node->vexnum; i++)
	{
		if (v == node->vexs[i])
		{
			return i;//返回下标
		}
		else
		{
			/*printf("顶点不存在\n");*/
		}
	}
	return -1;
}


//创建无向图
void creategraph1(g* node)
{
	//输入边数和顶点数
	printf("输入顶点数:");
	scanf("%d", &node->vexnum);
	printf("输入边数:");
	scanf("%d", &node->edgenum);
	//用户输入顶点
	for (int i = 0; i < node->vexnum; i++)
	{
		printf("请输入第%d个顶点:",i+1);
		scanf(" %c", &node->vexs[i]);
		/*fflush(stdin);*/
	}
	//矩阵初始化
	for (int i = 0; i < node->vexnum; i++)
	{
		for (int j = 0; j < node->vexnum; j++)
		{
			node->arcs[i][j] = 0;//让矩阵置空为0,即点都不连通
		}
	}
	//构建无向图的邻接矩阵
	char v1, v2;
	int n, m;
	printf("请输入边之间的关系(例:AB连通->AB):\n");
	for (int i = 0; i < node->edgenum; i++)
	{
		/*fflush(stdin);*/
		scanf(" %c%c", &v1,&v2);
		n = location(node, v1);//获取顶点的下标
		m = location(node, v2);
		if (n == -1 || m == -1)
		{
			printf("顶点不存在\n");
			return;
		}
		else
		{
			node->arcs[n][m] = 1;//无向图只要连通就是1
			node->arcs[m][n] = 1;
		}
	}
}

//创建有向图
void creategraph2(g* node)
{
	//输入顶点数和边数
	printf("请输入顶点数:");
	scanf("%d", &node->vexnum);
	printf("请输入边数:");
	scanf("%d", &node->edgenum);
	//输入顶点
	for (int i = 0; i < node->vexnum; i++)
	{
		printf("请输入第%d个顶点:", i + 1);
		scanf(" %c", &node->vexs[i]);
	}
	//邻接矩阵初始化
	for (int i = 0; i < node->vexnum; i++)
	{
		for (int j = 0; j < node->vexnum; j++)
		{
			node->arcs[i][j] = 0;
		}
	}
	//创建有向图的邻接矩阵
	char v1, v2;
	int n, m;
	printf("请输入边之间的关系(例:AB有序连通->AB):\n");
	for (int i = 0; i < node->edgenum; i++)
	{
		scanf(" %c%c", &v1,&v2);
		n = location(node, v1);
		m = location(node, v2);
		if (n == -1 || m == -1)
		{
			printf("顶点不存在\n");
			return;
		}
		else
		{
			node->arcs[n][m] = 1;//有方向所以只要一个
		}
	}
}

void print1(g* node)
{
	printf("邻接矩阵为:\n");
	for (int i = 0; i < node->vexnum; i++)
	{
		printf("\t%c", node->vexs[i]);
	}
	printf("\n");
	for (int i = 0; i < node->vexnum; i++)
	{
		printf("%c\t", node->vexs[i]);
		for (int j = 0; j < node->vexnum; j++)
		{
			printf("%d\t", node->arcs[i][j]);
		}
		printf("\n\n");
	}
}

//队列结构体
typedef struct queue
{
	int data[max];
	int front;
	int rear;
}que;

//初始化队列
void initque(que* qu)
{
	qu->front = qu->rear = 0;
}

//判断队空
int empty(que* qu)
{
	if (qu->front == qu->rear)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

//入队
void push(que* qu, int x)
{
	if (qu->rear + 1 == max)
	{
		printf("队满无法入队");
	}
	else
	{
		qu->data[qu->rear] = x;
		qu->rear++;
	}
}

//出队
int pop(que* qu)
{
	int temp;
	if (qu->rear == qu->front)
	{
		printf("队列为空无法出队\n");
	}
	else
	{
		qu->front++;
		temp = qu->data[qu->front - 1];
		return temp;
	}
}

//打印队列
void print(que* node)
{
	if (node->front == node->rear)
	{
		printf("队列为空无法打印\n");
	}
	else
	{
		printf("当前队列为:\n");
		for (int i = node->front; i < node->rear; i++)
		{
			printf("%d\t", node->data[i]);
		}
		printf("\n");
	}
}

//深度优先算法DFS
void DFSuse1(g* node,int i)
{
	printf("%c\t", node->vexs[i]);
	visit[i] =TRUE;
	for (int j = 0; j < node->vexnum; j++)
	{
		if (node->arcs[i][j] == 1 && !visit[j])
		{
			DFSuse1(node, j);
		}
	}
}

void DFS1(g* node)
{
	int i;
	for (i = 0; i < node->vexnum; i++)
	{
		visit[i] = FALSE;
	}
	for (i = 0; i < node->vexnum; i++)
	{
		if (!visit[i])
		{
			DFSuse1(node, i);
		}
	}
}


//广度优先算法BFS
void BFSuse1(g* node, int k)
{
	int i, j;
	que* qu;
	qu = (que*)malloc(sizeof(que));
	initque(qu);
	visit[k] = TRUE;
	push(qu, k);
	printf("%c\t", node->vexs[k]);
	while (empty(qu) != 1)
	{
		i = pop(qu);
		for (j = 0; j < node->vexnum; j++)
		{
			if (node->arcs[i][j] == 1 && !visit[j])
			{
				printf("%c\t", node->vexs[j]);
				visit[j] = TRUE;
				push(qu, j);
			}
		}
	}
}

void BFS1(g* node)
{
	for (int i = 0; i < node->vexnum; i++)
	{
		visit[i] = FALSE;
	}
	for (int i = 0; i < node->vexnum; i++)
	{
		if (!visit[i])
		{
			BFSuse1(node, i);
		}
	}
}

//图的邻接表实现
//顶点存在一维数组中,边的信息存在链表中
//边表的结构体
typedef struct Edge
{
	int edgedata;//数据域,存储顶点的下标
	struct Edge* next;//指针域
}edge;

//顶点表的结构体
typedef struct Vnode
{
	char nodedata;//真实数据
	edge* next_to_edge;
}vn, vnode[max];

//图的结构体
typedef struct listgraph
{
	vnode nodelist;
	int list_edgenum;
	int list_vexnum;
}lg;

//邻接表创建无向图
void creategraph3(lg* node)
{
	edge* e;
	printf("输入顶点数:");
	scanf("%d", &node->list_vexnum);
	printf("输入边数:");
	scanf("%d", &node->list_edgenum);
	//输入顶点
	for (int i = 0; i < node->list_vexnum; i++)
	{
		printf("请输入第%d个顶点:", i + 1);
		scanf(" %c", &node->nodelist[i].nodedata);
		node->nodelist[i].next_to_edge = NULL;
	}
	//邻接表初始化
	int v1, v2;
	printf("请输入边之间的关系(例:AB连通->01):\n");
	for (int i = 0; i < node->list_edgenum; i++)
	{
		scanf("%d %d", &v1,&v2);
		e = (edge*)malloc(sizeof(edge));
		e->edgedata = v2;
		e->next = node->nodelist[v1].next_to_edge;//把末尾结点的指针域给新结点
		node->nodelist[v1].next_to_edge = e;//原结点指针域后继为新结点
		
		e = (edge*)malloc(sizeof(edge));
		e->edgedata = v1;
		e->next = node->nodelist[v2].next_to_edge;//把末尾结点的指针域给新结点
		node->nodelist[v2].next_to_edge = e;//原结点指针域后继为新结点
	 
	}

}

//邻接表创建有向图
void creategraph4(lg* node)
{
	//输入边数和顶点数
	edge* e;
	printf("输入顶点数:");
	scanf("%d", &node->list_vexnum);
	printf("输入边数:");
	scanf("%d", &node->list_edgenum);
	//输入顶点
	for (int i = 0; i < node->list_vexnum; i++)
	{
		printf("请输入第%d个顶点:", i + 1);
		scanf(" %c", &node->nodelist[i].nodedata);
		node->nodelist[i].next_to_edge = NULL;
	}
	//邻接表初始化
	int v1, v2;
	printf("请输入边之间的关系(例:AB连通->0 1):\n");
	for (int i = 0; i < node->list_edgenum; i++)
	{
		scanf("%d %d", &v1, &v2);
		e = (edge*)malloc(sizeof(edge));
		if (e == NULL)
		{
			printf("error!内存申请失败\a");
			return;
		}
		else
		{
			e->edgedata = v2;
			e->next = node->nodelist[v1].next_to_edge;//把末尾结点的指针域给新结点
			node->nodelist[v1].next_to_edge = e;//原结点指针域后继为新结点
		}
	}
}

//邻接表的打印
void print2(lg* node)
{
	edge* e;
	printf("邻接表为:\n");
	for (int i = 0; i < node->list_vexnum; i++)
	{
		e = node->nodelist[i].next_to_edge;
		while (e != NULL)
		{
			printf("结点 %c ->结点 %c\t\t", node->nodelist[i].nodedata, node->nodelist[e->edgedata].nodedata);
			e = e->next;
		}
		printf("\n\n");
	}
}

//邻接表的深度优先DFS
int visited1[max];
void DFSuse2(lg* node, int i)
{
	edge* p;
	visited1[i] = 1;
	printf("%c\t", node->nodelist[i].nodedata);
	p = node->nodelist[i].next_to_edge;
	while (p)
	{
		if (!visited1[p->edgedata])
		{
			DFSuse2(node, p->edgedata);
		}
		p = p->next;
	}
}
void DFS2(lg* node)
{
	printf("*");
	int i;
	for (i = 0; i < node->list_vexnum; i++)
	{
		visited1[i] = 0;
	}
	for (i = 0; i < node->list_vexnum; i++)
	{
		if (!visited1[i])
		{
			DFSuse2(node, i);
		}
	}
}

//邻接表的BFS
int visit2[max];
void BFS2(lg* node)
{
	que* qu = (que*)malloc(sizeof(que));
	for (int i = 0; i < node->list_vexnum; i++)
	{
		visit2[i] = 0;
	}
	initque(qu);
	for (int i = 0; i < node->list_vexnum; i++)
	{
		visit2[i] = 1;
		printf("*");
		printf("%c\n", node->nodelist[i].nodedata);
		push(qu, i);
		while (empty(qu) != 1)
		{
			pop(qu);
			edge* e = node->nodelist[i].next_to_edge;
			while (e)
			{
				if (!visit2[e->edgedata])
				{
					visit2[e->edgedata] = 1;
					printf("%c\n", node->nodelist[e->edgedata].nodedata);
					push(qu, e->edgedata);
				}
				e = e->next;
			}
			printf("\n");
		}
	}
}


 
int main()
{
	int choose;
	g* node = (g*)malloc(sizeof(g));
	lg* listnode = (lg*)malloc(sizeof(lg));
	while (1)
	{
		printf("*****************************图的基本操作*****************************\n");
		printf("*****************************1.创建无向图(邻接矩阵)*****************\n");
		printf("*****************************2.创建有向图(邻接矩阵)*****************\n");
		printf("*****************************3.创建无向图(邻接表)*******************\n");
		printf("*****************************4.创建有向图(邻接表)*******************\n");
		printf("*****************************5.广度优先算法(邻接矩阵)***************\n");
		printf("*****************************6.深度优先算法(邻接矩阵)***************\n");
		printf("*****************************7.广度优先算法(邻接表)*****************\n");
		printf("*****************************8.深度优先算法(邻接表)*****************\n");
		printf("*****************************10.退出exit******************************\n");
		printf("**********************************************************************\n");
		printf("请输入你的选择:");
		scanf("%d", &choose);
		if (choose == 10)
		{
			printf("程序退出》》》");
			break;
		}
		switch (choose)
		{
			case 1:
				creategraph1(node);
				print1(node);
				break;
			case 2:
				creategraph2(node);
				print1(node);
				break;
			case 3:
				creategraph3(listnode);
				print2(listnode);
				break;
			case 4:
				creategraph4(listnode);
				print2(listnode);
				break;
			case 5:
				printf("图的邻接矩阵广度优先遍历为:\n");
				BFS1(node);
				printf("\n");
				break;
		    case 6:
				printf("图的邻接矩阵深度优先遍历为:\n");
				DFS1(node);
				printf("\n");
				break;
			case 7:
				printf("图的邻接表广度优先遍历为:\n");
				BFS2(listnode);
				printf("\n");
				break;
			case 8:
				printf("图的邻接表深度优先遍历为:\n");
				DFS2(listnode);
				printf("\n");
				break;
			default:
				printf("error!\a\n");
				break;
		}
	}
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值