生成树,非最小生成树,通过DFS、BFS,c/c++描述

  图的生成树,是图的连通子图,包含了图里所有顶点,但只含有顶点数减一条边。树里任何两个顶点都有通路。但树里没有环路。
  生成树的过程和图的遍历过程类似,遍历时,图里每个顶点都会出现且仅出现一次。
  因为表达树的途径,是表达出树里所有的边,边用边的两个顶点表示。生成树的过程,是要考虑如何输出所有的边的两个顶点。
  在DFS和BFS的程序代码基础上,修改代码,表达出生成树的过程。言虽简单,但也很巧妙。我也是看了书中代码,才明白的。自己虽然写过DFS,BFS,但跟书中代码一样简洁的思路,想不到。当然,咱们也能想出自己的思路。
  全部代码如下,先是main函数所在源文件:

#include<iostream>
#include<stdio.h>
using namespace std;
#define NUMVERTEX 11
#define INFINI 65555

struct GraphAdjaMatrix {
	char vertexes[NUMVERTEX];
	int edges[NUMVERTEX][NUMVERTEX];
	int numVertexes;
	int numEdges;
};

struct AdjaListNode {
	int indexOfVertex;
	int weightOfEdge;
	AdjaListNode* pt;
};

struct AdjListHead {
	char vertex;
	AdjaListNode* pt;
};

struct GraphAdjaList {
	AdjListHead vertexes[NUMVERTEX];
	int numVertexes;
	int numEdges;
};

extern void createGraphAdjMatrix(GraphAdjaMatrix &graphAdjMatrix,
			int numVertexes,int numEdges,int edges[][NUMVERTEX],char vertexes[]);
extern void createGraphAdjList(GraphAdjaList& graphAdjList,
	int numVertexes, int numEdges, int edges[][NUMVERTEX], char vertexes[]);
extern void dispalyGraphAdjMatrix(GraphAdjaMatrix &graphAdjMatrix);
extern void displayGrapgAdjList(GraphAdjaList& graphAdjList);
extern void spanningTreeDFS(GraphAdjaList& graphAdjList,int start,bool visited[]);
extern void spanningTreeBFS(GraphAdjaList& graphAdjList,int start,bool visited[]);

int main() {
	GraphAdjaMatrix graphAdjMatrix ;
	GraphAdjaList graphAdjList;

	int numEdges = 13;
	int edges[][NUMVERTEX] = {	
		{0,1,1,1,INFINI,INFINI,INFINI,INFINI,INFINI,INFINI,INFINI},
		{1,0,INFINI,INFINI,1,1,INFINI,INFINI,INFINI,INFINI,INFINI},
		{1,INFINI,0,1,INFINI,1,1,INFINI,INFINI,INFINI,INFINI},
		{1,INFINI,1,0,INFINI,INFINI,INFINI,1,INFINI,INFINI,INFINI},
		{INFINI,1,INFINI,INFINI,0,INFINI,INFINI,INFINI,INFINI,INFINI,INFINI},
		{INFINI,1,1,INFINI,INFINI,0,INFINI,INFINI,INFINI,INFINI,INFINI},
		{INFINI,INFINI,1,INFINI,INFINI,INFINI,0,1,1,1,INFINI},
		{INFINI,INFINI,INFINI,1,INFINI,INFINI,1,0,INFINI,INFINI,1},
		{INFINI,INFINI,INFINI,INFINI,INFINI,INFINI,1,INFINI,0,INFINI,INFINI},
		{INFINI,INFINI,INFINI,INFINI,INFINI,INFINI,1,INFINI,INFINI,0,INFINI},
		{INFINI,INFINI,INFINI,INFINI,INFINI,INFINI,INFINI,1,INFINI,INFINI,0}
	};
	char vertexes[] = {'0','1','2','3','4','5','6','7','8','9','S'};

	createGraphAdjMatrix(graphAdjMatrix,NUMVERTEX,numEdges,edges,vertexes);
	createGraphAdjList(graphAdjList,NUMVERTEX,numEdges,edges,vertexes);

	dispalyGraphAdjMatrix(graphAdjMatrix);
	displayGrapgAdjList(graphAdjList);
	cout << endl;

	cout << "spanning tree DFS : " << endl;
	bool visited[NUMVERTEX];
	for (int i = 0; i < NUMVERTEX; i++)
		visited[i] = false;
	spanningTreeDFS(graphAdjList,3,visited);

	for (int i = 0; i < NUMVERTEX; i++)
		visited[i] = false;
	cout << endl << "spanning tree BFS : " << endl;
	spanningTreeBFS(graphAdjList,3,visited);

	return 0;
}

接着是各函数所在源文件代码:

#include<iostream>
#include<stdio.h>
using namespace std;
#define NUMVERTEX 11
#define INFINI 65555

struct GraphAdjaMatrix {
	char vertexes[NUMVERTEX];
	int edges[NUMVERTEX][NUMVERTEX];
	int numVertexes;
	int numEdges;
};

struct AdjaListNode {
	int indexOfVertex;
	int weightOfEdge;
	AdjaListNode* pt;
};

struct AdjListHead {
	char vertex;
	AdjaListNode* pt;
};

struct GraphAdjaList {
	AdjListHead vertexes[NUMVERTEX];
	int numVertexes;
	int numEdges;
};

void createGraphAdjMatrix(GraphAdjaMatrix &graphAdjMatrix,
	int numVertexes, int numEdges, int edges[][NUMVERTEX], char vertexes[]) {
	graphAdjMatrix.numVertexes = numVertexes;
	graphAdjMatrix.numEdges = numEdges;
	
	for (int i = 0; i < numVertexes; i++)
		graphAdjMatrix.vertexes[i] = vertexes[i];

	for (int row = 0; row < numVertexes; row++)
		for (int column = 0; column < numVertexes; column++)
			graphAdjMatrix.edges[row][column] = edges[row][column];
}

void createGraphAdjList(GraphAdjaList &graphAdjList,
	int numVertexes, int numEdges, int edges[][NUMVERTEX], char vertexes[]){
	graphAdjList.numEdges = numEdges;
	graphAdjList.numVertexes = numVertexes;

	for (int i = 0; i < numVertexes; i++)
		graphAdjList.vertexes[i].pt = NULL;

	for (int i = 0; i < numVertexes; i++)
		graphAdjList.vertexes[i].vertex = vertexes[i];

	AdjaListNode* ptTail = NULL,*ptNew;
	int i, j;
	for ( i = 0; i < numVertexes; i++) 
		for (j = 0; j < numVertexes; j++) 
			if (edges[i][j] != 0 && edges[i][j] != INFINI) {
				ptNew = new AdjaListNode;

				ptNew->indexOfVertex = j;
				ptNew->weightOfEdge = edges[i][j];
			
				if (graphAdjList.vertexes[i].pt == NULL) {
					ptNew->pt = NULL;
					graphAdjList.vertexes[i].pt = ptNew;
					ptTail = ptNew;
				}
				else {
					ptNew->pt = ptTail->pt;
					ptTail->pt = ptNew;
					ptTail = ptNew;
				}
			}
}


void dispalyGraphAdjMatrix(GraphAdjaMatrix &graphAdjMatrix) {
	cout << "adjacensy matrix :" << endl;
	int row,column;
	printf("%3c",' ');
	for (row = 0; row < graphAdjMatrix.numVertexes; row++)
		printf("%3c",graphAdjMatrix.vertexes[row]);
	printf("\n");
	for (row = 0; row < graphAdjMatrix.numVertexes; row++) {
		printf("%-3c", graphAdjMatrix.vertexes[row]);
		for (column = 0; column < graphAdjMatrix.numVertexes; column++)
			if (graphAdjMatrix.edges[row][column] == INFINI)
				printf("%3s", "∞");
			else
				printf("%3d",graphAdjMatrix.edges[row][column]);
		cout << endl;
	}
}

void displayGrapgAdjList(GraphAdjaList &graphAdjList) {
	cout << "graph adjacency list : " << endl;
	AdjaListNode* pt;
	int index;
	for (int i = 0; i < graphAdjList.numVertexes; i++) {
		printf("%2c:",graphAdjList.vertexes[i].vertex);
		pt = graphAdjList.vertexes[i].pt;
		while (pt != NULL) {
			index = pt->indexOfVertex;
			printf("%5c(%d)",graphAdjList.vertexes[index].vertex,pt->weightOfEdge);
			pt = pt->pt;
		}
		cout << endl;
	}
}

void spanningTreeDFS(GraphAdjaList& graphAdjList,int start,bool visited[]) {
	visited[start] = true;

	AdjaListNode* pt = graphAdjList.vertexes[start].pt;
	while (pt != NULL) {
		if (visited[pt->indexOfVertex] == false) {
			cout << '(' << graphAdjList.vertexes[start].vertex << ',';
			cout << graphAdjList.vertexes[pt->indexOfVertex].vertex << ")   ";
			spanningTreeDFS(graphAdjList,pt->indexOfVertex,visited);
		}
		pt = pt->pt;
	}
}

void spanningTreeBFS(GraphAdjaList& graphAdjList,int start,bool visited[]) {
	int queue[NUMVERTEX * 2],tail = 0,head = 0;
	queue[tail] = start;
	visited[start] = true;

	AdjaListNode* pt;
	while (head <= tail) {
		pt = graphAdjList.vertexes[queue[head]].pt;
		while (pt != NULL) {
			if (visited[pt->indexOfVertex] == false) {
				cout << '(' << graphAdjList.vertexes[queue[head]].vertex << ',';
				cout << graphAdjList.vertexes[pt->indexOfVertex].vertex << ')' << "   ";
				visited[pt->indexOfVertex] = true;
				
				tail++;
				queue[tail] = pt->indexOfVertex;
			}
			
			pt = pt->pt;
		}
		head++;
	}
}

图和测试结果和对应的生成树如下,因为顶点用字符表示,所以以字符S代表10号顶点:
在这里插入图片描述
在这里插入图片描述
对DFS和BFS代码的改编,需要对深度优先和广度优先遍历的过程有深刻的理解。以上过程结果也是正确的。谢谢阅读。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值