数据结构与算法——图的实现

图的存储结构:

邻接矩阵表示法

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>


using namespace std;

#define MaxInt 32767   // 用来表示无穷大
#define MVNum 20    // 最大顶点数
typedef char VerTexType;   // 设顶点数据类型为字符型
typedef int ArcType;    //设边的权值类型为整型


// 邻接矩阵表示法:
typedef struct AMGraph
{
	VerTexType vexs[MVNum];    // 图的顶点表
	ArcType arcs[MVNum][MVNum];    // 邻接矩阵

	int vexnum, arcnum;   // 图当前点数和边数
};

// 用邻接矩阵创建无向网 —— 无向图,有向图,有向网类似
void CreateUDN(AMGraph& G)
{
	// 第一步:输入无向图的顶点数和边数
	cout << "请输入无向图的顶点数和边数!" << endl;
	cin >> G.vexnum >> G.arcnum;  // 输入总顶点数和总边数

	// 第二步:依次输入顶点信息(名称)到一维数组中
	for (int i = 0; i < G.vexnum; i++)
	{
		cin >> G.vexs[i];
	}
	
	// 第三步:初始化邻接矩阵
	for (int i = 0; i < G.vexnum; i++)
	{
		for (int j = 0; j < G.vexnum; j++)
		{
			G.arcs[i][j] = MaxInt;   // 边的权值设为无穷大
		}
	}

	// 第四步:构造邻接矩阵,输入顶点相互关系以及权重
	for (int k = 0; k < G.arcnum; k++)
	{
		int i, j, weight;
		char v1, v2;    // 顶点信息
		cin >> v1 >> v2 >> weight;
		// 根据输入的信息在顶点表中查找对应的顶点的下标
		i = LocateVex(G, v1);
		j = LocateVex(G, v2);

		G.arcs[i][j] = weight;   // 顶点v1与v2之间的权值赋值为 weight;
		G.arcs[j][i] = G.arcs[i][j];   // 无向图 —— 对称矩阵
	}
}

// 在图G中查找顶点 u
int LocateVex(AMGraph G, VerTexType u)
{
	for (int i = 0; i < G.vexnum; i++)
	{
		if (u == G.vexs[i])
		{
			return i;
		}
	}
	return -1;
}

// 深度优先搜索遍历算法:
// 先创建visited数组用以判断某个点到没到过
int visited[MVNum] = {};

void DFS(AMGraph G, int v)
{
	// 输入最开始的访问结点序号
	cout << v;
	cout << G.vexs[v];   // 由序号v查找图G中对应序号v的顶点内容;
	visited[v] = 1;  // 表示这个点被访问过了

	// 依次从开头检查邻接矩阵第v行的所有的元素
	for (int w = 0; w < G.vexnum; w++)
	{
		if ((G.arcs[v][w] == 1) && (visited[v] == 0))
		{
			// w 是 v 的邻接点,如果 w 未被访问,则递归调用DFS —— 递归算法嵌套调用,层层进入满足后再一层一层退出。
			// 返回到最后一层发现都访问过了,则结束循环。
			DFS(G, w);
		}
	}
}

 邻接表表示法

#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>


using namespace std;

#define MaxInt 32767   // 用来表示无穷大
#define MVNum 20    // 最大顶点数
typedef char VerTexType;   // 设顶点数据类型为字符型
typedef int ArcType;    //设边的权值类型为整型

// 邻接表表示法:
// 
// 顶点的结点结构
typedef struct VNode
{
	char data;   // 顶点信息
	ArcNode* firstarc;   // 指向第一条依附该顶点的边的指针
}VNode, AdjList[MVNum];   // AdjList表示邻接表类型 —— AdjList v = VNode v[MVNum]

// 边的结点结构
typedef struct ArcNode
{
	int adjvex;    // 该边所指向的顶点的位置
	struct ArcNode* nextarc;  // 指向下一条边的结点
	int weight;   // 边的权重
};

// 图的结构定义
struct ALGraph
{
	// 数组来保存顶点
	AdjList vertices;   // 等价于 VNode vexs[MVNum]
	//定义两个变量,保存当前图的顶点个数以及边的条数
	int vexnum, arcnum;
};

// 查找算法
int LocateVex(ALGraph G, VerTexType u)
{

}


// 创建无向图
void CreateUDG(ALGraph& G)
{
	// 第一步:输入无向图的顶点数和边数
	cout << "请输入无向图的顶点数和边数!" << endl;
	cin >> G.vexnum >> G.arcnum;  // 输入总顶点数和总边数

	// 第二步:依次输入顶点信息(名称)到表头节点表中
	for (int i = 0; i < G.vexnum; i++)
	{
		cin >> G.vertices[i].data;  // 输入顶点值
		G.vertices[i].firstarc = nullptr;   // 初始化表头结点的指针域
	}

	// 第三步:输入各边,构造邻接表
	for (int k = 0; k < G.arcnum; k++)
	{
		char v1, v2;   // 
		cin >> v1 >> v2;
		int i = LocateVex(G, v1);  // 查找 v1 和 v2 对应的下标
		int j = LocateVex(G, v2);

		// 生成新的边结点 *p1
		ArcNode* p1 = new ArcNode;
		p1->adjvex = j;   // 邻接点序号为 j
		p1->nextarc = G.vertices[i].firstarc;   // 头插法:先将p1的nextarc域赋值为nullptr
		G.vertices[i].firstarc = p1;   //

        // 第 j 个结点也要插入
		ArcNode* p2 = new ArcNode;
		p2->adjvex = i;
		//q->weight = w;
		p2->nextarc = G.vertices[j].firstarc;
		G.vertices[j].firstarc = p2;
	}
}


// 深度优先搜索遍历算法:
// 先创建visited数组用以判断某个点到没到过
int visited[MVNum] = {};

void DFS(ALGraph G, int v)
{
	// 访问序号v代表的顶点的内容
	cout << v;
	cout << G.vertices[v].data << endl;
	// 访问后记为1
	visited[v] = 1;

	ArcNode* p = G.vertices[v].firstarc;
	while (p != nullptr)
	{
		int i = p->adjvex;
		if (visited[i] == 0)
		{
			DFS(G, i);
		}
		p = p->nextarc;
	}
}

十字链表

 邻接多重表

遍历算法:1. 深度优先遍历算法(DFS);2. 广度优先遍历算法(BFS)。

        1. 深度优先遍历算法(DFS)

         2. 广度优先遍历(BFS)

 

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个,V是G中顶点的集合,E是G中边的集合。在中的数据元素,我们称之为顶点(Vertex),顶点集合有穷非空。在中,任意两个顶点之间都可能有关系,顶点之间的逻辑关系用边来表示,边集可以是空的。 按照边的有无方向分为无向和有向。无向由顶点和边组成,有向由顶点和弧构成。弧有弧尾和弧头之分,带箭头一端为弧头。 按照边或弧的多少分稀疏和稠密。如果中的任意两个顶点之间都存在边叫做完全,有向的叫有向完全。若无重复的边或顶点到自身的边则叫简单中顶点之间有邻接点、依附的概念。无向顶点的边数叫做度。有向顶点分为入度和出度。 上的边或弧带有权则称为网。 中顶点间存在路径,两顶点存在路径则说明是连通的,如果路径最终回到起始点则称为环,当中不重复的叫简单路径。若任意两顶点都是连通的,则就是连通,有向则称为强连通中有子,若子极大连通则就是连通分量,有向的则称为强连通分量。 无向中连通且n个顶点n-1条边称为生成树。有向中一顶点入度为0其余顶点入度为1的叫有向树。一个有向由若干棵有向树构成生成森林。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值