数据结构之图


#

逻辑结构与内存结构#

结构实现#

  • 邻接矩阵实现
  • 邻接表实现
typedef int VertexType;
typedef struct  ArcNode
{
	/*单链表中结点类型*/
	int adjvex;				//该边指向的顶点在顺序表中的位置
	int* weight;			//边的权重
	struct ArcNode* next;	//下一条边
}ArcNode;

typedef struct
{
	VertexType data;		//顶点中的数据信息
	ArcNode* firstarc;		//指向单链表,即第一条边

}VNode;

方法#

  • 生成图
  • 深度优先遍历
  • 广度优先遍历

重要算法#

最小生成树算法
  • Kruskal算法(加边法)(用并查集实现)

  • 并查集

  • Prim算法(加点法)

拓扑排序
  • 拓扑排序算法
  • 关键路径求解算法
最短路径算法
  • 迪杰斯特拉算法
  • 弗洛伊德算法

在这篇文章中我就只放上生成图以及深搜宽搜等算法,后面会专门上图的其他重要算法

基础生成等算法#

#include<iostream>
#include<queue>

using namespace std;

typedef int VertexType;

int visited[20];

typedef struct ArcNode
{
	/*单链表中结点的类型*/
	int adjvex;					//邻接点在主顺序表中的下标
	int weight;					//与该邻接点形成的边的权值
	struct ArcNode* next;		//下一个邻接点 即边
}ArcNode;

typedef struct VNode
{
	VertexType data;			//该点所存储的数据
	ArcNode* firstArc;			//第一个邻接点
}VNode;

void CreateGraph(VNode G[], int n);
int FitstAdj(VNode G[], int v);
int NextAdj(VNode G[], int v);
void DFS_Travel(VNode G[], int v);
void DFS(VNode G[], int n);
void BFS(VNode G[], int v);
void BFS_Travle(VNode G[], int n);

//int main()
//{
//	return 0;
//}
//生成图
void CreateGraph(VNode G[], int n)
{/*
 图的生成算法有很多很多,一般都只需要根据题目输入要求进行改动就行了,这里是
 按每个节点顺序来输入边的。
 */
	for (int i = 0; i < n; i++)
	{
		G[i].data = i;					//顶点i
		G[i].firstArc = NULL;			//初始化将邻边置NULL
		ArcNode* p = NULL,*q = NULL;
		int v;							//输入邻接点 v
		cin >> v;
		while (v!=-1)					//一次记录输入邻接点v,当输入-1时表明此顶点i已经录完所有的邻接点了
		{
			q = new ArcNode;			//对邻接点v初始化数据
			q->adjvex = v;
			q->next = NULL;
			q->weight = 0;
			if (G[i].firstArc == NULL)	//判断是否是第一个邻接点,如果是就连着顶点i的第一个位置
				G[i].firstArc = q;
			else						//如果不是第一个就连着前一个邻接点的后面
				p->next = q;
			p = q;						//p始终在邻接点q的前一个
			cin >> v;					//输入下一个邻接点,如果是-1将退出到下一个顶点的数据录入
		}
	}
}
//获得该点的首个邻接点的下标
int FitstAdj(VNode G[], int v)		
{
	if (G[v].firstArc != NULL)			//获取顶点v的第一个邻接点
		return G[v].firstArc->adjvex;
	else
		return -1;					//说明该点无邻接点
}
//获得下一个未访问的邻接点
int NextAdj(VNode G[], int v)
{
	if (G[v].firstArc == NULL)			//说明顶点v无邻接点
		return -1;
	else
	{
		ArcNode* p = G[v].firstArc;		//p标记为v的邻接点
		while (p != NULL)				
		{
			if (visited[p->adjvex] == 0)//如果该邻接点未被访问过
				return p->adjvex;		//返回该节点下标
			else
				p = p->next;			//该邻接点被访问过 进入到下一个邻接点的判断
		}
		return -1;						//说明所有的邻接点都被访问了,返回-1表明无邻接点了
	}
}
//深度优先遍历实现

void DFS(VNode G[], int n)
{
	for (int i = 0; i < n; i++)
	{
		visited[i] = 0;					//将所有节点初始化为未访问状态
	}
	for (int i = 0; i < n; i++)
	{
		if (visited[i] == 0)			//如果该节点i没有访问过就进行深度遍历
		{
			DFS_Travel(G, i);
		}
	}
}
//深度优先遍历
/*
深度优先遍历,对于一个节点v,会先访问它的一个邻接点,然后以这个邻接点为起点去访问这个邻接点的邻接点,这样
就渐渐的往下延申,当不能再延申的时候再往前回退一下,就像树根在土里往下延申一样,这是我的一点理解
*/
void DFS_Travel(VNode G[],int v)
{
	cout << G[v].data << endl;			//访问节点v的内容
	visited[v] = 1;						//将节点v的状态置为已经访问过
	int w = FitstAdj(G, v);				//获取节点v的第一个邻接点
	while (w != -1)						//如果存在邻接点
	{
		if (visited[w] == 0)			//判断该邻接点是否访问过,没有访问则以该节点开始进行深度遍历
			DFS_Travel(G, w);
		w = NextAdj(G, v);				//获得节点v的下一个邻接点
	}
}
//广度优先实现
/*
广度优先:对于节点v 广度优先遍历会先访问v的所有邻接点,将v的邻接点访问完后就开始访问v的邻接点的所有邻接点,
这样就像在一圈一圈散出去,这是我比较值观的理解。
*/
void BFS(VNode G[], int v)
{
	queue<int> q;						//用队列来存储邻接点下标
	cout << G[v].data << endl;			//访问元素
	visited[v] = 1;						//访问状态置为已经访问
	q.push(v);							//入队列
	int w;								//标记邻接点
	while (!q.empty())					//循环为队列非空
	{
		v = q.front();					//将队头元素出队列
		q.pop();
		w = FitstAdj(G, v);				//获得首个邻接点
		while (w != -1)
		{
			if (visited[w] == 0)		//如果该节点没有访问过
			{
				cout << G[w].data << endl;//访问元素
				visited[w] = 1;			//访问状态置为已经访问
				q.push(w);				//将该节点入队列
			}
			w = NextAdj(G, v);			//寻找下一个未访问的邻接点
		}
	}
}
//广度优先遍历
void BFS_Travle(VNode G[], int n)
{
	for (int i = 0; i < n; i++)			//将所有点都置为未访问过
		visited[i] = 0;
	for (int i = 0; i < n; i++)		
	{
		if (visited[i] == 0)			//对没有访问过的节点进行广度优先访问
			BFS(G, i);
	}
}```

作者:墨鱼-yyyl

出处:https://www.cnblogs.com/moyu-yyyl/p/18009720

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   墨鱼yyyl  阅读(5)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示