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