无向图中的深度优先生成森林
2015-10-14 15:50
411 查看
在对无向图进行遍历时,对于连通图,仅需要从图中的任意一个顶点出发,进行深度优先搜索或广度优先搜索,便可访问到图中所有顶点。对于非连通图,则需从多个顶点出发进行搜索,而每一次从一个新的起点出发进行搜索过程中得到的顶点访问序列恰为其各个连通分量中顶点集。对于非连通图,每个连通分量中的顶点集,和遍历时走过的边一起构成若干棵生成树,这些连通分量的生成树组成非连通图的生成森林。我们以孩子兄弟链表作为深度优先生成森林的存储结构,时间复杂度为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
相关文章推荐
- vss简介
- 数组replaceObjectAtIndex
- linux硬盘分区格式化及挂载
- UsbAccessory和UsbDevice的区别
- css文字双竖排显示
- 微信朋友圈发二维码会被屏蔽
- 判断IE6 CSS 通过判断浏览器类型而加载不同的css样式
- mac 下 tomcat安装
- zookeeper的集群模式下的安装和配置
- Mac中MySQL无法显示中文全解决
- ibox上lubuntu更新edubuntu桌面
- 十大常用数据结构
- 第7周 项目1 - 建立顺序环形队列算法库
- -drawRect学习总结
- Java集合总结(未完待续)
- 利用Tag值获取所在行的数组下标。购物车中的移除功能,
- 多线程通信 --- 多个生产者多个消费者
- 网络编程实践陈硕笔记一
- 浅谈HTTP,TCP,UDP
- 第十二章、私营部门和第三部门中的采购