图论基础(图的存储和遍历)

图论是数据结构中最重要的一章。笔者打算将其分为几篇文章发布出来。本篇文章主要实现了图的存储和遍历,由于BFS,所以本节中用到了STL模板中的队列。比较尴尬的是,笔者这里的实现不适用于算法竞赛,可看但不好用,真正算法竞赛中都用数组实现的。但这种繁琐的代码实现有助于加深我们对图的熟悉程度,间接有利于解决图的问题。后面笔者准备发布“图的应用”的代码,会使用笔者认为较为方便的代码风格,同时也会加上例题,加深读者对这些应用的感受。现在校内数据结构课程似乎对数据结构应用代码的不足够重视,笔者认为一方面是因为实现难度较大,不方便考察,另一方面可能就是因为代码风格不适用于实现和解题。

#include"stdio.h"
#include"stdlib.h"  //该文件中包含malloc和free()

//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
//Status是函数的类型,其值是函数结果状态代码
typedef int Status;

//邻接矩阵
#define MVNum 100  //最大顶点数
#define MaxInt 32767 //表示两个点之间的距离无穷大,即不存在边
typedef char VerTexType;   //假设顶点类型是char
typedef int ArcType;    //假设边权类型是int

typedef struct
{
	VerTexType vexs[MVNum];  //顶点表
	ArcType arcs[MVNum][MVNum];  //邻接矩阵
	int vexnum,arcnum;  //顶点数和边数
}AMGraph;


//采用邻接矩阵的方法创建无向网
int LocateVex(AMGraph G,VerTexType u)  //用于寻找点的下标的函数
{
	for (int i = 0;i < G.vexnum;i++)
	{
		if (u == G.vexs[i]) return i;
	}
	return -1;
}

Status CreateUDN(AMGraph &G)
{
	scanf("%d %d", &G.vexnum, &G.arcnum);  //输入顶点和边的总数
	for (int i = 0;i < G.vexnum;i++)
	{
		scanf("%c", &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 v1, v2, w;
		scanf("%c %c %d", &v1, &v2, &w);
		int i = LocateVex(G, v1); 
		int j = LocateVex(G, v2);
		G.arcs[i][j]=G.arcs[j][i] = w; //因为无向图,对称
	}
	return OK;
}


//邻接表存储图
//边结点的数据结构
typedef int OtherInfo;
typedef struct ArcNode
{
	int adjvex;  //该边所指向的顶点的位置
	struct ArcNode *nextarc;  //指向下一条边的结点
	OtherInfo info;  //和边相关的信息
}ArcNode;

//表头结点数据类型
typedef struct VNode
{
	VerTexType data;  //顶点信息
	ArcNode  * firtarc;  //指向第一条边的指针
}VNode,AdjList[MVNum]; //AdjList表示邻接表类型,AdjList v = VNode v[MVNum]

//图结构的定义
typedef struct
{
	VNode vertices[MVNum];
	int vexnum, arcnum;
}ALGraph;

//采用邻接表的方法创建无向网
int LocateVex(ALGraph G, VerTexType u)  //用于寻找点的下标的函数
{
	for (int i = 0;i < G.vexnum;i++)
	{
		if (u == G.vertices[i].data) return i;
	}
	return -1;
}

Status CreateUDG(ALGraph &G)
{
	scanf("%d %d", &G.vexnum, &G.arcnum);  //输入顶点和边的总数
	for (int i = 0;i < G.vexnum;i++)
	{
		scanf("%c", &G.vertices[i].data);  //输入顶点信息
		G.vertices[i].firtarc = NULL;
	}
	for (int k = 0;k < G.arcnum;k++)
	{
		VerTexType v1,v2;
		scanf("%c %c", &v1, &v2);
		int i = LocateVex(G, v1);
		int j = LocateVex(G, v2);

		ArcNode *p1 = (ArcNode*)malloc(sizeof(ArcNode));
		p1->adjvex = j;
		p1->nextarc = G.vertices[i].firtarc;
		G.vertices[i].firtarc = p1;  //利用头插法,将一条边 插入单链表中
		//由于无向图,还要再进行一次操作

		ArcNode *p2 = (ArcNode*)malloc(sizeof(ArcNode));
		p2->adjvex = i;
		p2->nextarc = G.vertices[j].firtarc;
		G.vertices[j].firtarc = p1;  //利用头插法,将一条边 插入单链表中
	}
	return OK;
}

//图的遍历
//邻接矩阵实现DFS深度优先搜索(时间复杂度为n2)
int visited[MVNum];
void DFS(AMGraph G, int v)  //这里每结点用一个整数来表示,结点序号为 1-n
{
	printf("%d", v); //访问结点
	visited[v] = true;
	for (int w = 1;w <= G.vexnum;w++)
	{
		if (G.arcs[v][w] != 0 && !visited[w])
		{
			DFS(G, w);
		}
	}
}

//邻接表实现广度优先搜索
#include<iostream>
using namespace std;
#include<queue>
queue<int>Q;  //加入STL模板,便利直接使用队列

int visited2[MVNum];

void BFS(AMGraph G, int v)
{
	printf("%d", v);
	visited2[v] = true;
	Q.push(v);
	while (!Q.empty())
	{
		int u = Q.front();
		Q.pop();
		for(int w = /*FirstAdjVex(G, u)*/0;w >= 0;w = /*NextAdjVex(G, u, w)*/0)  //w为u尚未访问过的邻接顶点,实际操作时遍历邻接表
		{
			if (!visited[w])
			{
				printf("%d", w);
				visited2[w] = true;
				Q.push(w);
			}
		}
	}
}

int main()
{

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值