对于无向图,从任意一个顶点出发,根据深度优先遍历,可以得到一个连通分量。对于非连通图,每一次从一个未访问的顶点出发,可以得到多个连通分量。将这些通过深度优先遍历求得连通分量构成一棵棵生成树,并以兄弟孩子链表,将这些生成树以森林的形式存储。
将这个森林(二叉树)进行先序遍历,得到的结果和深度优先遍历的结果一致!
参考:数据结构c语言版
以下面非连通无向图为例:
原图:
生成深度优先森林(孩子兄弟结构)
输入图的信息
0 (表示无向图)
10 (节点数目)
10(弧数目)
1 2 0 (弧的两个端点,权重)
1 3 0
2 4 0
2 5 0
3 6 0
3 7 0
4 8 0
5 8 0
6 7 0
9 10 0
(邻接链表表示)
V1--> < 3 , 0 > --> < 2 , 0 >
V2--> < 5 , 0 > --> < 4 , 0 > --> < 1 , 0 >
V3--> < 7 , 0 > --> < 6 , 0 > --> < 1 , 0 >
V4--> < 8 , 0 > --> < 2 , 0 >
V5--> < 8 , 0 > --> < 2 , 0 >
V6--> < 7 , 0 > --> < 3 , 0 >
V7--> < 6 , 0 > --> < 3 , 0 >
V8--> < 5 , 0 > --> < 4 , 0 >
V9--> < 10 , 0 >
V10--> < 9 , 0 >
C++ 代码实现:
森林结构
class CSNode
{
public:
CSNode();
~CSNode();
CSNode(int d) ;
void setDate(int d) ;
void setFirstChild(CSNode *firstC);
void setNextBrother(CSNode *nextB) { nextBrother = nextB; }
int getDate() ;
CSNode *getFirstChild() ;
CSNode *getNextBrother() ;
private:
int data;
CSNode *firstChild;
CSNode *nextBrother;
};
class CSTree
{
public:
CSTree() { root = NULL; }
CSTree(CSNode * r) { root = r; }
CSNode *getRoot() { return root; }
void setRoot(CSNode * r) { root = r; }
void printCSTree(); // 深度优先森林树的先序遍历,即深度优先搜索结果
private:
CSNode * root;
};
生成生成树核心代码:
void ALGraph::ALGraphDFS(CSNode*root) // 指定某个节点广度优先搜索
{
ArcNode* arcnode;
CSNode*ch = NULL;
VNode *vnode;
int vIndex;
int start = root->getDate();
vnode = &(vetices[start]);
vetices[start].setVColor('g');
arcnode = vnode->getFirstArc();
int first = 1; // 标识为第一个邻接点
for (; arcnode != NULL; arcnode = arcnode->getNextarc())
{
vIndex = arcnode->getAdjvex() - 1;
if (vetices[vIndex].getVColor() == 'w')
{
vetices[vIndex].setVColor('g');
ch = new CSNode(vIndex);
if (first)
{
root->setFirstChild(ch);
first = 0;
}
else
{
root->getFirstChild()->setNextBrother(ch);
}
ALGraphDFS(ch);
}
}
}
void ALGraph::getCSTree(CSTree* T)
{
CSNode *root = NULL, *eldBrother = NULL; // 单棵树的根节点
vector<VNode*> vistNodeVec;
for (int vIndex = 0; vIndex < this->getVexNum(); vIndex++)
{
this->vetices[vIndex].setVColor('w');
}
for (int vIndex = 0; vIndex < this->getVexNum(); vIndex++)
{
if (this->vetices[vIndex].getVColor() == 'w')
{
vetices[vIndex].setVColor('g');
if (!T->getRoot()) // 森林的第一个根节点
{
root = new CSNode(vIndex);
T->setRoot(root);
}
else
{
root = new CSNode(vIndex);
eldBrother->setNextBrother(root);
}
eldBrother = root;
ALGraphDFS(root); // 建立以 root 为根的生成树
}
}
}
主函数:
#include<iostream>
#include "ALGraph.h"
using namespace std;
void main()
{
ALGraph *alGraph = new ALGraph();
alGraph->createALGraph();
alGraph->printALGraph();
alGraph->ALGraphBFS();
alGraph->ALGraphDFS();
CSTree *T = new CSTree();
alGraph->getCSTree(T);
T->printCSTree();
}
完整代码下载地址:
http://download.youkuaiyun.com/detail/lmx2014001/9622467