基础数据结构(一)图的实现(邻接矩阵+邻接表)+BFS广度优先搜索+DFS深度优先搜索

 1、图的邻接矩阵表示法

#include <iostream>
/*
	图 G = (V, E);
		   /    \
    n个顶点集合  边的集合(两个顶点之间有没有边)
		图分为3种:
			无向图、有向图
			网(边带权的图)
*/
#define MAXSIZE 100
typedef char VerTexType;//顶点值的数据类型
typedef int ArcType;//无向图、有向图直接用0、1表示两个顶点之间有没有边
					//网直接用边的权、无穷大值表示两个顶点之间有没有边	
#define NoArc 65535//网的两个顶点之间没有边的情况
typedef struct AMGraph
{
	VerTexType vexs[MAXSIZE];//顶点集合 一维数组
	ArcType arcs[MAXSIZE][MAXSIZE];//边的集合 二维数组
	int curvexs;//当前顶点的数目
	int curarcs;//当前边的数目
} AMGraph;

//构造图(初始化)
int CreatUDN(AMGraph & G);
//补充:在图中查找顶点并返回下标
int Locate(AMGraph G, VerTexType v);

int main()
{


	return 0;
}

//构造图(初始化)
int CreatUDN(AMGraph & G)
{
	/*
		1、输入顶点的总数、边的总数
		2、构造顶点表
		3、构造邻接矩阵
	*/
	int v;
	int a;
	std::cout << "Enter the num of Vertexs: ";
	std::cin >> v;
	G.curvexs = v;
	std::cout << "Enter the num of Arcs: ";
	std::cin >> a;
	G.curarcs = a;
	for (int i = 0; i < G.curvexs; i++)
	{
		std::cout << "Enter the val of Vertexs: ";
		std::cin >> G.vexs[i];
	}
	//初始化--所有顶点之间都没有边
	for (int j = 0; j < NoArc; j++)
	{
		for (int k = 0; k < NoArc; k++)
			G.arcs[j][k] = NoArc;
	}
	/*std::cout << "Enter the val of Arcs: ";
	for (int m = 0; m < G.curvexs; m++)
	{
		for (int n = 0; n < G.curvexs; n++)
			std::cin >> G.vexs[m][n];
	}*/
	//利用无向图的邻接阵是对称的
	VerTexType v1, v2;
	ArcType weight;//边的权值
	int m, n;//用来接收顶点所在顶点表中的位置
	for (int k = 0; k < G.curarcs; k++)
	{
		std::cin >> v1 >> v2 >> weight;//边依附于哪两个顶点
		m = Locate(G, v1);
		n = Locate(G, v2);
		G.arcs[m][n] = G.arcs[n][m] = weight;//无向图的邻接阵是对称阵
	}
	return 1;
}
//补充:在图中查找顶点并返回下标
int Locate(AMGraph G, VerTexType v)
{
	for (int i = 0; i < G.curvexs; i++)
	{
		if (G.vexs[i] == v)
			return i + 1;
	}
	return 0;
}

2、图的邻接表表示法

#include <iostream>
/*
	G = (V, E);
		/
	n个顶点的集合(顺序存储)一维数组实现
		/
		要存储的数据
		该顶点与哪几个顶点之间有边(非固定的)(边链表实现)
*/
#define MAXSIZE 100
//i顶点的边链表
typedef struct Node
{
	int loc;//出度顶点的下标
	Node * next;//下一个(出度顶点)链结点的位置
} *LinkList;
//i顶点
typedef char VerTexsType;
typedef struct Vertexs
{
	VerTexsType data;
	LinkList L;//i顶点的边链表(i顶点与哪些顶点之间有边)
} VerTexs;
//图
typedef struct AMGraph
{
	VerTexs vexs[MAXSIZE];
	int vexnum;//当前共有多少个顶点
	int arcnum;//当前共有多少边
} AMGraph;
//构造1个图
int CreateGraph(AMGraph & G);
//在图中找顶点
int Locate(AMGraph G, VerTexsType v);

int main()
{


	return 0;
}

//构造1个图
int CreateGraph(AMGraph & G)
{
	/*
		1、输入顶点总数、边总数
		2、依次输入G的顶点表的值
		   把顶点表的每个元素的边链表头指针置空
		3、输入边依附于的两个顶点
		   找出顶点对应的下标i, j 
		   新建2个链结点并初始化,分别进行头插  顶点表的头指针
	*/
	int v, a;
	std::cout << "Enter the num of Vertexs: ";
	std::cin >> v;
	std::cout << "Enter the num of Arcs: ";
	std::cin >> a;
	G.vexnum = v;
	G.arcnum = a;
	std::cout << "Enter the val of Vertexs: ";
	for (int i = 0; i < G.vexnum; i++)
	{
		std::cin >> G.vexs[i].data;
		G.vexs[i].L = nullptr;
	}
	std::cout << "Enter the pointer of Vertexs:\n";
	std::cout << "Enter the arc between two vertexs: ";
	VerTexsType m, n;
	int p, q;
	Node * ln1, *ln2;
	for (int j = 0; j < G.arcnum; j++)
	{
		std::cin >> m >> n;
		p = Locate(G, m);
		q = Locate(G, n);
		//新建两个链结点
		ln1 = new Node;
		ln1->loc = p;
		ln1->next = nullptr;
		ln2 = new Node;
		ln2->loc = q;
		ln2->next = nullptr;
		//分别头插
		ln2->next = G.vexs[p].L->next;
		G.vexs[p].L = ln2;
		ln1->next = G.vexs[q].L->next;
		G.vexs[q].L = ln1;
	}
	return 1;
}
//在图中找顶点
int Locate(AMGraph G, VerTexsType v)
{
	for (int i = 0; i < G.vexnum; i++)
	{
		if (G.vexs[i].data == v)
			return i;
	}
	return -1;
}

3、 BFS广度优先搜索

#include <iostream>
/*
	图 G = (V, E);
		   /    \
	n个顶点集合  边的集合(两个顶点之间有没有边)
		图分为3种:
			无向图、有向图
			网(边带权的图)
*/
#define MAXSIZE 100
typedef char VerTexType;//顶点值的数据类型
typedef int ArcType;//无向图、有向图直接用0、1表示两个顶点之间有没有边
					//网直接用边的权、无穷大值表示两个顶点之间有没有边	
#define NoArc 65535//网的两个顶点之间没有边的情况
typedef struct AMGraph
{
	VerTexType vexs[MAXSIZE];//顶点集合 一维数组
	ArcType arcs[MAXSIZE][MAXSIZE];//边的集合 二维数组
	int curvexs;//当前顶点的数目
	int curarcs;//当前边的数目
} AMGraph;

//图的广度优先搜索DFS
void BFS(AMGraph G, int v);
//辅助数组(用来判断i顶点是否被访问过)
int visited[MAXSIZE] = { 0 };//实际长度应该为n个顶点
//单向队列--浪费内存
#define MAXSIZE 100
typedef struct
{
	int data[MAXSIZE];//静态数组
	int head;//头指针(队头元素)
	int rear;//尾指针(队尾元素的下一个位置)
} Queue;
//初始化为空队列
void InitQueue(Queue &Q);
//队空?
int EmptyQueue(Queue Q);
//队满
int FullQueue(Queue Q);
//入队
int EnQueue(Queue & Q, int e);
//出队
int DelQueue(Queue & Q, int & e);

int main()
{


	return 0;
}

//图的广度优先搜索DFS
void BFS(AMGraph G, int v)
{
	/*
		1、从v顶点出发, visited[v] = 1, visited[v]入队;
		2、判断队列非空--v顶点出队, 遍历邻接矩阵的第v行v的所有邻接点并入队
	*/
	Queue Q;
	InitQueue(Q);
	std::cout << v << '\t';
	visited[v] = 1;
	EnQueue(Q, v);
	int e;
	while (!EmptyQueue(Q))
	{
		DelQueue(Q, e);
		for (int w = 0; w < G.curvexs; w++)
		{
			if (G.arcs[e][w] != 0)
			{
				std::cout << e << '\t';
				visited[w] = 1;
				EnQueue(Q, w);
			}
		}

	}
}
//初始化为空队列
void InitQueue(Queue &Q)
{
	Q.head = Q.rear = 0;
}
//队空?
int EmptyQueue(Queue Q)
{
	if (Q.head == Q.rear)
		return 1;
	else
		return 0;
}
//队满
int FullQueue(Queue Q)
{
	if (Q.rear == MAXSIZE)
		return 1;
	else
		return 0;
}
//入队
int EnQueue(Queue & Q, int e)
{
	if (!FullQueue(Q))
	{
		Q.data[Q.rear++] = e;
		return 1;
	}
	else
		return 0;
}
//出队
int DelQueue(Queue & Q, int & e)
{
	if (!EmptyQueue(Q))
	{
		e = Q.data[Q.head++];
		return 1;
	}
	else
		return 0;
}

4、 DFS深度优先搜索 

#include <iostream>
/*
	图 G = (V, E);
		   /    \
	n个顶点集合  边的集合(两个顶点之间有没有边)
		图分为3种:
			无向图、有向图
			网(边带权的图)
*/
#define MAXSIZE 100
typedef char VerTexType;//顶点值的数据类型
typedef int ArcType;//无向图、有向图直接用0、1表示两个顶点之间有没有边
					//网直接用边的权、无穷大值表示两个顶点之间有没有边	
#define NoArc 65535//网的两个顶点之间没有边的情况
typedef struct AMGraph
{
	VerTexType vexs[MAXSIZE];//顶点集合 一维数组
	ArcType arcs[MAXSIZE][MAXSIZE];//边的集合 二维数组
	int curvexs;//当前顶点的数目
	int curarcs;//当前边的数目
} AMGraph;

//图的深度优先搜索DFS
void DFS(AMGraph G, int v);
//辅助数组(用来判断i顶点是否被访问过)
int visited[MAXSIZE] = {0};//实际长度应该为n个顶点

int main()
{


	return 0;
}

//图的深度优先搜索DFS
void DFS(AMGraph G, int v)
{
	/*
		1、从v顶点出发, 辅助数组visited[v]置1
		2、访问邻接矩阵的第v行
			如果第1个非0元素G.arcs[v][w] != 0且该顶点未被访问visited[w] != 1则递归调用DFS(G, w);
		递归出口visited[k] = 1且 G.arcs[k][] = 0
	*/
	std::cout << v << "\t";//输出该顶点信息
	visited[v] = 1;
	for (int w = 0; w < G.curvexs; w++)//访问邻接矩阵第v行
	{
		if (G.arcs[v][w] != 0 && visited[w] != 1)//第1个非0元素且顶点未被访问过
			DFS(G, w);//则递归调用, 从该顶点出发
	}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

汪呈祥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值