看数据结构写代码(40) 无向图的深度优先生成树与广度优先生成树

图的深度优先遍历 和 广度 优先 遍历 算法中的 每一次 最外层 循环 都 产生 一个 无向图 的 连通分量,每一个连通分量,都可以产生一个生成树,将这些生成树合在 一起 就是 一个 森林。 用 树的 孩子 兄弟 链表 表示法 来 表示 这个 森林, 就是 这一节 算法的  内容。

深度优先森林 代码 :

//深度优先生成森林
void dfsTree(AMLGraph g,int i,Tree * t,bool isVisited[]){
	isVisited[i] = true;
	bool isFirst = true;
	Tree p,q = NULL;
	for (int next = firstAdj(g,i); next != -1; next = nextAdj(g,i,next)){
		if (isVisited[next] == false){
			p = makeTreeNode(g.adjMuList[next].vexName);
			if (isFirst){
				(*t)->firstChild = p,isFirst = false;
			}
			else{
				q->nextSibling = p;
			}
			q = p;
			dfsTree(g,next,&q,isVisited);
		}

	}
}


void dfsForest(AMLGraph g,Tree * t){
	bool isVisited[MAX_VEX_NUM] = {false};
	*t = NULL;
	Tree p,q;
	for (int i = 0; i < g.vexNum; i++){
		if (isVisited[i] == false){
			p = makeTreeNode(g.adjMuList[i].vexName);//每一次循环都是一颗生成树.
			if (*t == NULL){//第一个是根节点
				*t = p;
			}
			else{//其余生成树 是 第一颗 生成树的 兄弟
				q->nextSibling = p;
			}
			q = p;//保存上一个树
			dfsTree(g,i,&q,isVisited);
		}
	}
}
广度优先生成森林代码:

//广度优先生成森林
void bfsForest(AMLGraph g,Tree * t){
	bool isVisited[MAX_VEX_NUM] = {false};
	Tree treeArray[MAX_VEX_NUM] = {NULL};//记录所有顶点的 树节点坐标.
	//因为要 找到 遍历的 树节点的 父亲 是谁.(这一句p = treeArray[top];)
	Tree p,q,r;
	LinkQueue queue;
	queueInit(&queue);
	for (int i = 0; i < g.vexNum; i++){
		if (isVisited[i] == false){
			p = makeTreeNode(g.adjMuList[i].vexName);
			if (i == 0){//第一颗生成树..
				*t = p;
			}
			else{//其他生成树是 第一颗生成树的 孩子兄弟链表的 兄弟
				//(*t)->nextSibling = p; 这样写 就只有 一个兄弟节点了..
				q->nextSibling = p;
			}
			q = p;
			treeArray[i] = p;
			isVisited[i] = true;
			enqueue(&queue,i);
			while (!queueEmpty(queue)){
				int top;
				dequeue(&queue,&top);
				bool isFirst = true;
				for (int next = firstAdj(g,top);next != -1; next = nextAdj(g,top,next)){
					if (isVisited[next] == false){
						isVisited[next] = true;
						r = makeTreeNode(g.adjMuList[next].vexName);
						treeArray[next] = r;
						if (isFirst){
							p = treeArray[top];
							p->firstChild = r,isFirst = false;
						}
						else{
							p->nextSibling = r;
						}
						p = r;
						enqueue(&queue,next);
					}
				}
			}
		}
	}
	queueDestory(&queue);
}
在写广度 优先生成森林代码中,犯了 两个错误:

1.

//(*t)->nextSibling = p; 这样写 就只有 一个兄弟节点了..
q->nextSibling = p;

2.

没有 写 这句话:

p = treeArray[top];

后来 将所有 顶点的坐标 存到 数组中,好查找 节点的 父亲节点。


详细源代码如下:

工程文件网盘地址:点击打开链接

// AMLGraph.cpp : 定义控制台应用程序的入口点。
//无向图的邻接多重表

#include "stdafx.h"
#include <cstdlib>
#include "queue.h"
#include "BinaryTree.h"

#define MAX_VEX_NUM 20

enum E_VisitIf
{
	unvisited = 0,
	visited = 1,
};
struct ArcNode
{
	E_VisitIf mark;
	int iIndex,jIndex;//顶点i,j在图中的位置
	ArcNode * iNext;//与i顶点点相关的下一个弧
	ArcNode * jNext;//与j顶点点相关的下一个弧
};

struct VNode
{
	char vexName;
	ArcNode * head;//头指针
};

struct AMLGraph
{
	VNode adjMuList[MAX_VEX_NUM];//顶点数组
	int vexNum,arcNum;
};

//获取弧 的 头节点
ArcNode * getHeadNode(){
	ArcNode * pNode = (ArcNode *)malloc(sizeof(ArcNode));
	if (pNode){
		pNode
  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值