无向图中的深度优先生成森林

来源:互联网 发布:watchout软件多少钱 编辑:程序博客网 时间:2024/05/17 07:52
在对无向图进行遍历时,对于连通图,仅需要从图中的任意一个顶点出发,进行深度优先搜索或广度优先搜索,便可访问到图中所有顶点。对于非连通图,则需从多个顶点出发进行搜索,而每一次从一个新的起点出发进行搜索过程中得到的顶点访问序列恰为其各个连通分量中顶点集。对于非连通图,每个连通分量中的顶点集,和遍历时走过的边一起构成若干棵生成树,这些连通分量的生成树组成非连通图的生成森林。我们以孩子兄弟链表作为深度优先生成森林的存储结构,时间复杂度为o(n + e)。
#include<iostream>#include<fstream>#include<vector>#include<time.h>#include<algorithm>using namespace std;struct CSTree{int data;CSTree * lchild;CSTree * nextsibling;};void DFSTree(int v,CSTree *&p);void DFSForest(CSTree *&root);CSTree *root = NULL;//生成森林bool *visited;vector<vector<int>> mGraph;//图结构int nodeNum;//图中顶点数int edgeNum;//图中边数void readGraph(){fstream fin("E:\\myData\\facebook_combined.txt");//打开文件fin>>nodeNum>>edgeNum;//读取顶点数和边数mGraph.resize(nodeNum);//设置图的大小visited = new bool[nodeNum];for(int i = 0; i < nodeNum; ++i){visited[i] = false;}int num1, num2;while(fin>>num1>>num2)//读取每一条边{mGraph[num1].push_back(num2);//存储边的信息mGraph[num2].push_back(num1);}fin.close();//关闭文件for(int i = 0; i < nodeNum; ++i){sort(mGraph[i].begin(),mGraph[i].end());//图中节点的邻接点排序}}//建立无向图G的深度优先生成森林void DFSForest(CSTree *&root){CSTree *q = NULL;//指向当前生成树的根节点for(int i = 0; i < nodeNum; ++i){if(!visited[i])//当前节点没有被访问过{CSTree *p = new CSTree;//创建树中的节点p->data = i;p->lchild = NULL;p->nextsibling = NULL;if(root == NULL)//如果当前森林为空{root = p;//当前新生成的节点为森林的根节点}else{q->nextsibling = p;//当前根节点指向p}q = p;;DFSTree(i,q);//生成以q为根节点的深度优先生成树}}}//从第v个顶点出发深度优先遍历图,建立以root为根的树void DFSTree(int v,CSTree *&root){visited[v] = true;//当前节点标记为被访问过bool first = true;//当前节点的第一个孩子int count = mGraph[v].size();//v的邻接点的个数CSTree *q = NULL;//指向当前节点for(int i = 0; i < count; ++i){int val = mGraph[v][i];if(!visited[val])//当前节点没有被访问过{visited[val] = true;//设置当前节点被访问过CSTree *p = new CSTree;//新生成一个节点p->data = val;p->lchild = NULL;p->nextsibling = NULL;if(first)//当前节点的第一个孩子{root->lchild = p;first = false;}else//当前节点的其他孩子{q->nextsibling = p;}q = p;DFSTree(val,p);}}}//以前序遍历的方式输出森林void show(CSTree *root){if(root != NULL){cout<<root->data<<" ";show(root->lchild);show(root->nextsibling);}}int main(void){readGraph();cout<<"无向图中顶点的个数:"<<nodeNum<<endl;cout<<"无向图中边的条数:"<<edgeNum<<endl;clock_t start,end;start = clock();DFSForest(root);end = clock();cout<<"生成森林时间:"<<float(end - start)/CLOCKS_PER_SEC*1000<<endl;system("pause");return 0;}
实验结果:单位为(ms)
数据集为soc-Epinions
无向图中顶点的个数:75888
无向图中边的条数:508837
生成森林时间:67
数据集为facebook_combined
无向图中顶点的个数:4039
无向图中边的条数:88234
生成森林时间:4
0 0
原创粉丝点击