Day17:图

目录

一、基本概念 

 二、代码实现:

①代码的框架

 ②初始化、创建、show函数的实现

③寻找第一个临近节点,寻找第二个临近节点

④DFS和BFS

一、基本概念 

1.多对多的数据结构 - 图
2.构成: 
        顶点                                                       vertexs
        边:   用来描述顶点之间的关系             edges
3.描述图的方式:

        临接表:链表
        临接矩阵:数组

4.网图:边有长度(权值)

                A星寻路算法:
                    f = g + h
                    f = g + h + w其中的w就是可能的权值

5.图的遍历:
        深度优先遍历:Deap First Search
            一路往下遍历,没有了再换周围其他节点
        广度优先遍历:Breadth First Search
            先把周围的遍历完,然后再往下搜索

关键实现函数:

        找某个顶点的第一个相邻顶点
        找某个顶点的第二个相邻顶点

 二、代码实现:

注:这里的DFS采用递归的方法实现.

①代码的框架

include <iostream>
#include <stdio.h>

#include <queue>

using namespace std;
//临界矩阵描述图

#define VERTEXS  6
#define EDGES	 7	

//图类型
struct Graph
{
	int		vertexs;		//顶点个数
	int		edges;			//边条数
	char*	pVertex;		//指向  存储所有顶点的一维数组
	int**	pEdge;			//二级指针   描述矩阵
};

//创建图对象
Graph*	createGraph();
//初始化图对象
void initGraph(Graph* g, int vertexs, int edges, char* v, int map[VERTEXS][VERTEXS]);
//显示图对象
void showGraph(Graph* g);
//从图中找到参数顶点在顶点数组中的下标并返回
int _getIndex(Graph* g, char c);

//找beg参数对应顶点的第一个相邻顶点,找到了返回其下标,没找到返回-1  isFind数组标记有没有找过
int findFirstVertex(Graph* g, int beg, bool isFind[VERTEXS]);
//找beg参数对应顶点的第二个相邻顶点,找到了返回其下标,没找到返回-1  isFind数组标记有没有找过
int findNextVertex(Graph* g, int beg, bool isFind[VERTEXS]);

void DFS(Graph* g, char beg, bool isFind[VERTEXS]);
void BFS(Graph* g, char beg, bool isFind[VERTEXS]);

void travel(Graph* g, char beg,bool isD=true)
{
	bool  isFind[VERTEXS] = { 0 };

	if (isD)
	{
		printf("深度优先遍历:%c ", beg);
		DFS(g, beg, isFind);
		printf("\n");
	}
	else
	{
		printf("广度优先遍历:%c ", beg);
		BFS(g, beg, isFind);
		printf("\n");
	}

}

int main()
{
	Graph* g = createGraph();
	char buff[7] = "ABCDEF";
	int map[VERTEXS][VERTEXS] = 
	{
		{ 0, 1, 0, 1, 0, 0 },
		{ 1, 0, 1, 0, 0, 0 },
		{ 0, 1, 0, 1, 1, 1 },
		{ 1, 0, 1, 0, 0, 1 },
		{ 0, 0, 1, 0, 0, 0 },
		{ 0, 0, 1, 1, 0, 0 }
	};
	initGraph(g, VERTEXS, EDGES, buff, map);
	showGraph(g);

	//	travel(g, 'A');
	travel(g, 'A',1);

	while (1);
	return 0;
}

 ②初始化、创建、show函数的实现

//创建图对象
Graph*	createGraph()
{
	Graph* pNew = new Graph;
	if (NULL == pNew) return NULL;
	memset(pNew, 0, sizeof(Graph));
	return pNew;
}

//初始化图对象
void initGraph(Graph* g, int vertexs, int edges, char* v, int map[VERTEXS][VERTEXS])
{
#if 1
	//1 开内存
	g->vertexs = vertexs;
	g->edges = edges;

	g->pVertex = new char[g->vertexs];
	g->pEdge = new int*[g->vertexs];
	for (int i = 0; i < g->vertexs; i++)
	{
		g->pEdge[i] = new int[g->vertexs];
	}
	//2 数据拷贝
	memcpy(g->pVertex, v, sizeof(char)*g->vertexs);
	for (int i = 0; i < g->vertexs; i++)
	{
		memcpy(g->pEdge[i], map[i], sizeof(int)*g->vertexs);
	}
#else
	//1 开内存
	//此处最好也是用户输入
	g->vertexs = vertexs;
	g->edges = edges;

	g->pVertex = new char[g->vertexs];
	g->pEdge = new int*[g->vertexs];
	for (int i = 0; i < g->vertexs; i++)
	{
		g->pEdge[i] = new int[g->vertexs];
		memset(g->pEdge[i], 0, sizeof(int)*g->vertexs);
	}

	printf("请输入顶点:");
	scanf("%s", g->pVertex);//输入的时候自行把握 不要越界

	char buff[5] = { 0 };
	char src, dst;
	int  srcIdx, dstIdx;
	for (int i = 0; i < g->edges; i++)
	{
		printf("请输入第%d条边:", i + 1);
		scanf("%s", buff);// A->B
		src = buff[0];
		dst = buff[3];

		srcIdx = _getIndex(g, src);
		dstIdx = _getIndex(g, dst);

		g->pEdge[srcIdx][dstIdx] = 1;
#if 1  //如果是无向图  加这一行
		g->pEdge[dstIdx][srcIdx] = 1;
#endif
	}
#endif
}
//从图中找到参数顶点在顶点数组中的下标并返回
int _getIndex(Graph* g, char c)
{
	for (int i = 0; i < g->vertexs; i++)
	{
		if (c == g->pVertex[i]) return i;
	}
	return -1;
}
//显示图对象
void showGraph(Graph* g){
	for (int i = 0; i <= g->vertexs; i++)
	{
		for (int j = 0; j <= g->vertexs; j++)
		{
			if (0 == i && 0 == j)
			{
				printf("  ");
			}
			else if (0 == i)
			{//第一行
				printf("%c ", g->pVertex[j - 1]);
			}
			else if (0 == j)
			{//第一列
				printf("%c ", g->pVertex[i - 1]);
			}
			else
			{//才是里面对应的数字
				printf("%d ", g->pEdge[i - 1][j - 1]);
			}
		}
		printf("\n");
	}
}

③寻找第一个临近节点,寻找第二个临近节点

//找beg参数对应顶点的第一个相邻顶点,找到了返回其下标,没找到返回-1  isFind数组标记有没有找过
int findFirstVertex(Graph* g, int beg, bool isFind[VERTEXS])
{
	for (int i = 0; i < g->vertexs; i++)
	{
		if (isFind[i]) continue;
		if (1 == g->pEdge[beg][i]) return i;			//找到beg对应的那一行,邻接矩阵中遇到的第一个就是第一个相邻的顶点
	}
	return -1;
}

//找beg参数对应顶点的第二个相邻顶点,找到了返回其下标,没找到返回-1  isFind数组标记有没有找过
int findNextVertex(Graph* g, int beg, bool isFind[VERTEXS])
{
	for (int i = beg+1; i < g->vertexs; i++)
	{//注:为什么i是从beg+1开始的,是因为用的时候传入的CurrentIdx,也就是第一次找到的下标---->+1就能从后面开始搜
		if (isFind[i]) continue;
		if (1 == g->pEdge[beg][i]) return i;
	}
	return -1;
}

④DFS和BFS

//递归实现栈的回退
void DFS(Graph* g, char beg, bool isFind[VERTEXS])
{
	//找beg的第一个相邻顶点x ,继续找x的第一个相邻顶点y 直到没有找到  结束
	int currentIdx = _getIndex(g,beg);
	isFind[currentIdx] = 1;//每递归到一个,就标记一个.

	int nextIdx = findFirstVertex(g, currentIdx, isFind);
	while (1)
	{
		if (-1 == nextIdx) break;
		if (false == isFind[nextIdx])
		{
			printf("%c ", g->pVertex[nextIdx]);
			DFS(g, g->pVertex[nextIdx],isFind);
		}
		nextIdx = findNextVertex(g, currentIdx, isFind);
	}
}
void BFS(Graph* g, char beg, bool isFind[VERTEXS])
{
	queue<int> q;

	q.push(_getIndex(g, beg));//把第一个放到队列里
	isFind[_getIndex(g, beg)] = true;

	int headIdx;
	int idx;
	while (!q.empty())
	{//step1:找出队首的元素,保存并在队列中删除
		headIdx = q.front();//队列头  第一个
		q.pop();//删掉第一个

	//step2:把刚才保存的顶点的相邻的顶点都放到队列中
		idx = findFirstVertex(g, headIdx, isFind);//找到头结点的邻接的结点  while 找出全部的.
		while (1)
		{
			if (-1 == idx) break;
			if (!isFind[idx])
			{
				isFind[idx] = true;//每push进去一个,就标记一个
				printf("%c ", g->pVertex[idx]);
				q.push(idx);
			}
			idx = findNextVertex(g, headIdx, isFind);
		}
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Ocean__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值