有向图(网)、无向图(网)的构造以及遍历

构造图采用的是邻接表的方法,然后采用深度和广度优先进行遍历。(博主第一次写构造方法的时候花了很久写的很冗杂,虽然也实现了,但是感觉到处都在打补丁,拼拼凑凑写出来的,后来用了一分钟重写了一个,秒通过!!!欲哭无泪啊~原因主要是因为不同的输入格式导致的,以后些其他代码的时候要慎重考虑输入的格式问题)

下面贴代码!

根据书上的伪代码,写出定义的结构

const int MAX_VERTEX_NUM = 20;
bool visited[MAX_VERTEX_NUM];    //遍历访问标志

typedef struct ArcNode{
	int adjvex;    //该弧所指向的顶点的位置
	struct ArcNode *nextarc;    //指向下一条弧(边)的指针
	int weight;    //该弧(边)的权值
}ArcNode;

typedef struct VNode{
	char data;    //顶点信息
	ArcNode *firstarc;    //指向第一条依附该顶点的弧(边)的指针
}VNode,AdjList[MAX_VERTEX_NUM];

typedef struct{
	AdjList vertices;    
	int vexnum, arcnum;    //图的当前顶点数和弧(边)数
	int kind;
}ALGraph;

根据书上的伪代码,写出三个要用到的方法

//返回顶点v在图G中的位置
int LocateVex(ALGraph G, char v)
{
	for (int i = 0; i < G.vexnum; i++){
		if (v == G.vertices[i].data)
			return i;
	}
	return -1;
}

//返回v的第一个邻接顶点
int FirstAdjVex(ALGraph G, int v)
{
	if (G.vertices[v].firstarc)
		return G.vertices[v].firstarc->adjvex;
	return -1;
}

//返回顶点v相对于邻接点w的下一个邻接点
int NextAdjVex(ALGraph G, int v, int w)
{
	ArcNode *p;
	p = G.vertices[v].firstarc;
	if (p){
		while (p){
			if (w == p->adjvex){
				if (nullptr == p->nextarc)
					return -1;
				else
					return p->nextarc->adjvex;
			}
			p = p->nextarc;
		}
	}
	return -1;
}

下面是本体,一分钟改写出的构造图的方法!

//采用邻接表构造图G
void CreateGraph(ALGraph &G)
{
	int i, j, weight;
	char v, v1, v2;
	ArcNode *p, *q = nullptr;
	cout << "请输入图类型的序号:\n1.DG(有向图)\n2.DN(有向网\n3.UDG(无向图)\n4.UDN(无向网)" << endl;
	cin >> G.kind;
	cout << "请输入图G的顶点数和弧(边)数:";
	cin >> G.vexnum >> G.arcnum;
	//构造邻接表
	for (i = 0; i < G.vexnum; i++){
		cout << "请输入顶点vex[" << i << "]的值:";
		cin >> G.vertices[i].data;
		G.vertices[i].firstarc = nullptr;
	}
	cout << endl;
	for (j = 0; j < G.arcnum; j++){
		cout << "请输入第" << j << "条弧(边)的两个端点:";
		cin >> v1 >> v2;
		q = G.vertices[LocateVex(G, v1)].firstarc;
		p = new ArcNode;
		p->adjvex = LocateVex(G, v2);
		p->nextarc = nullptr;
		if (1 == G.kind || 3 == G.kind)
			p->weight = 1;
		else{
			cout << "请输入该弧(边)的权值:";
			cin >> weight;
			p->weight = weight;
		}

		if (q){
			while (q->nextarc)
				q = q->nextarc;
			q->nextarc = p;
		}
		else
			G.vertices[LocateVex(G, v1)].firstarc = p;

		if (3 == G.kind || 4 == G.kind){
			q = G.vertices[LocateVex(G, v2)].firstarc;
			p = new ArcNode;
			p->adjvex = LocateVex(G, v1);
			p->nextarc = nullptr;
			if (1 == G.kind || 3 == G.kind)
				p->weight = 1;
			else{
				p->weight = weight;
			}

			if (q){
				while (q->nextarc)
					q = q->nextarc;
				q->nextarc = p;
			}
			else
				G.vertices[LocateVex(G, v2)].firstarc = p;
		}
	}
}

根据书上的伪代码,写出深度优先遍历的递归方法

//深度优先遍历(递归)
void DFS(ALGraph G, int v)
{
	visited[v] = true;
	cout << G.vertices[v].data << " ";
	for (int i = FirstAdjVex(G, v); i >= 0; i = NextAdjVex(G, v, i)){
		if (!visited[i])
			DFS(G, i);
	}
}

void DFSTraverse(ALGraph G)
{
	int i;
	cout << "深度优先结果:" << endl;
	for (i = 0; i < G.vexnum; i++)
		visited[i] = false;
	for (i = 0; i < G.vexnum; i++){
		if (!visited[i])
			DFS(G, i);
	}
	cout << endl;
}

打印函数在测试的时候不可少

//打印邻接表
void PrintALGraph(ALGraph G)
{
	ArcNode *p;
	for (int i = 0; i < G.vexnum; i++){
		cout << G.vertices[i].data;
		if (G.vertices[i].firstarc){
			p = G.vertices[i].firstarc;
			while (p){
				if (3 == G.kind || 4 == G.kind)
					cout << " - " << G.vertices[p->adjvex].data;
				else
					cout << "→" << G.vertices[p->adjvex].data;
				p = p->nextarc;
			}
		}
		cout << endl;
	}
}

最后配上主函数

int main()
{
	ALGraph graph;
	CreateGraph(graph);
	PrintALGraph(graph);
	DFSTraverse(graph);

	system("pause");
	return 0;
}
    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/ckxal123/article/details/76648991
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞