图的建立与深度遍历

邻接表的简介

所谓邻接表,是指对图G中的每个顶点v建立一个单链表,第i个单链表中的结点表示依附于顶点 v的边(对于有向图则是以顶点v为尾的弧),这个单链表就称为顶点v的边表(对于有向图则称为出边表)。边表的头指针和顶点的数据信息采用顺序存储(称为顶点表),所以在邻接表中存在两种结点:顶点表结点和边表结点。
在这里插入图片描述
在这里插入图片描述

邻接矩阵的简介

所谓邻接矩阵存储,是指用一个一维数组存储图中顶点的信息,用一个二维数组存储图中边的信息(即各顶点之间的邻接关系),存储顶点之间邻接关系的二维数组称为邻接矩阵。

在这里插入图片描述

题目

用数组存储结构作为图的存储结构的前提下,试编制图的输入以及深度优先搜素遍历算法的有关子程序;编制主程序main()调用这些子程序;并输入遍历结结果

分析:即使用邻接矩阵存储图,然后使用DFS算法来遍历

代码部分

#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:6031)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "iostream"  //c++的输入输出语句

#define VertexNUM 100
#define INFO 65535

using namespace std;          //c++的标准命名  主要是为了下边cout和cin语句

typedef int elemTypeInt;
typedef char infoType,vertexType,elemTypeChar;

//邻接矩阵的顶点
typedef struct {
	elemTypeInt No; //顶点编号
	infoType info;  //  其他信息
}vertextype;

//邻接矩阵图
typedef struct {
	elemTypeInt edges[VertexNUM][VertexNUM];  //二维数组主体
	int vertexNum, edgeNum;                              //顶点数和边数
	vertextype vex[VertexNUM];             //顶点数组(一维)
}MGraph;

//邻接矩阵建立图
void creatMGraph(MGraph* G) {
	int i, j, k, w;
	cout << "请输入邻接表的顶点数和边数" << endl;          //C语言可用printf语句代替使用
	cin >> G->vertexNum;			//   顶点数        C语言使用scanf语句代替
	cin >> G->edgeNum;				//   边数		C语言使用scanf语句代替

	//矩阵赋值
	for (i = 0; i < G->vertexNum; i++) {
		for (j = 0; j < G->vertexNum; j++) {
			if (i == j)
				G->edges[i][j] = 0;//自身无边
			else
				G->edges[i][j] = INFO;  //无穷大,最开始声明过 #define INFO 65535
		}
	}
	for (k = 0; k < G->edgeNum; k++) {
		cout << "请输入起始点和终点以及权值" << endl;          //C语言可用printf语句代替使用

		cin >> i;
		cin >> j;
		cin >> w;

		//无向边  即矩阵对称
		G->edges[i][j] = w;
		G->edges[j][i] = w;
	}
}

bool visit[VertexNUM];  //记录访问情况,访问l为true,否则为false

//深度优先遍历 对结点而言算法
void DFS(MGraph* G, int v) {  
	int i;
	visit[v] = true;
	for ( i = 1; i < G->vertexNum; i++)
		if (G->edges[v][i] != 0 && !visit[i]) //有边,同时还没有被访问过  另一种写法if (G->edges[v][i] != 0 && visit[i]==false)
			DFS(G, i);	
}

//对邻接矩阵而言的算法
void DFSTravers(MGraph* G) {
	int i;
	for (i = 0; i < G->vertexNum; i++)
		if (!visit[i])  // 另一种写法if( visit[i] == false)
			DFS(G, i);	
}

int main() {
	int i;

	MGraph* G1;
	creatMGraph(G1);
	DFSTravers(G1);
	for (i = 0; i < G1->vertexNum; i++)
		if (visit[i])
			cout << i << endl;
}

补充:邻接表已经邻接表对应的DFS

#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:6031)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "iostream"  //c++的输入输出语句

#define VertexNUM 100
#define INFO 65535

using namespace std;          //c++的标准命名  主要是为了下边cout和cin语句

typedef int elemTypeInt;
typedef char infoType,vertexType,elemTypeChar;


//************************** 邻接表 start ******************************//

//邻接表的边结点
typedef struct ArcNode {  
	elemTypeInt adjvex;
	struct ArcNode* nextArc;
	elemTypeInt info;
}ArcNode;

//邻接表的表顶点
typedef struct {
	vertexType data;
	ArcNode* first;
}VNode;

//邻接表的顶点数和边数
typedef struct {
	VNode adjlist[VertexNUM];
	int VertexNum, EdgeNum;    
}AGraph;

//************************** 邻接表 end ******************************//

//邻接表建立图
void creatAGraph(AGraph *G) {
	int i;  //主要用于下边的计数使用的
	G = (AGraph*)malloc(sizeof(AGraph));

	cout << "请输入邻接表的顶点数和边数" << endl;          //C语言可用printf语句代替使用
	cin >> G->VertexNum;			//   顶点数        C语言使用scanf语句代替
	cin >> G->EdgeNum;				//   边数		C语言使用scanf语句代替
	for (i = 1; i <= G->EdgeNum; i++) {     //从1开始编号
		cout << "请输入邻接表的顶点信息" << endl;  //C语言可用printf语句代替使用
		cin >> G->adjlist[i].data;
		G->adjlist[i].first = NULL;       //初始时,顶点之间不存在边
	}

	//边的信息
	vertexType v1, v2; //声明两个顶点
	ArcNode* p;
	for (i = 1; i <= G->EdgeNum; i++) {   //边从1开始编号
		cout << "请输入边的两端v1,v2(从1开始编号)" << endl;
		cin >> v1;   //v1<----->v2  之间有边
		cin >> v2;

		//无向边,所以需要建立两条边
		p = (ArcNode*)malloc(sizeof(ArcNode));   //申请边界点
		p->adjvex = v2;
		p->nextArc = G->adjlist[v1].first;
		G->adjlist[v1].first = p;

		p = (ArcNode*)malloc(sizeof(ArcNode));   //申请边界点
		p->adjvex = v1;
		p->nextArc = G->adjlist[v2].first;
		G->adjlist[v2].first = p;
	}
}




bool visit2[VertexNUM];
void DFS2(AGraph* G, int v) {
	ArcNode* p;
	visit2[v] = true;
	cout << G->adjlist[v].data;  //打印结点信息
	p = G->adjlist[v].first;
	while (p) {
		if (!visit2[p->adjvex])  //边尚未被访问
			DFS2(G, p->adjvex);
		p = p->nextArc;
	}
}

void DFSTravers2(AGraph* G) {
	int i;
	for (i = 0; i < G->VertexNum; i++)
		if (!visit[i])  // 另一种写法if( visit[i] == false)
			DFS2(G, i);
}


int main() {
	int i;

	AGraph* G2;
	creatAGraph(G2);
	DFSTravers2(G2);
	for (i = 0; i < G1->vertexNum; i++)
		if (visit[i])
			cout << i << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值