图的存储以及深度优先和广度优先
2016-01-02 20:51
369 查看
<span style="font-size:18px;"> </span><pre name="code" class="cpp">/* 图的存储与遍历 1.读取文件data中图的信息 2.创建图->临接矩阵 3.输出顶点以及临接矩阵 4.将临接矩阵存储转换为临接表存储 5.输出临接表 6.输出深度优先搜素结果 7.输出广度优先搜索结果 */ #include<iostream> #include<string> #include<sstream> #include<fstream> using namespace std; //定义矩阵存储空间 const int MAX_N = 100;//存储空间最大值 const int INF = 65535;//定义为无穷大 //图的矩阵存储 //顶点信息 class Vertex { public: int number;//定义定点下标 int verxname;//顶点名 }; //邻接矩阵存储图 class MGraph { public: int edages[MAX_N][MAX_N];//边数组 int weight[MAX_N];//权重 int Tvertexs, Tedges;//顶点及边总数 Vertex vert[MAX_N];//顶点信息 }; //临接表存储 class Anode; //顶点 class Vnode { public: int adjverx;//边终点编号 Anode *firstAnode;//下一顶点 }; //边 class Anode { public: int weight;//权重 int vesname;//顶点名称 Anode *nextAnode;//下一顶点 }; //临接表存储图 class FGraph { public: Vnode adjList[MAX_N];//顶点信息 int Tvertexs, Tedges;//总顶点数、边数 }; class Graph { public: Graph() { InitMatrix();//初始化临接矩阵 } ~Graph(){} //初始化 void InitMatrix() { for (int i = 0; i < MAX_N; i++) { for (int j = 0; j < MAX_N; j++) { mgraph.edages[i][j] = INF;//初始化为无穷大 } } } //初始化遍历数组 void InitVisited() { for (int i = 0; i < MAX_N; i++) { visited[i] = INF;//初始化为无穷大 } } //读取信息 void getInfo(string filename) { ifstream readfile; readfile.open(filename); getline(readfile, verx);//读取顶点信息 getline(readfile, weight);//读取权重 int i = 0; while (!readfile.eof()) { if (getline(readfile, edges[i]).good())//读取边 { i++; } } Tedges = i;//记录边数 } //创建图 void CreateGraphMatrix() { int edge1, edge2; mgraph.Tvertexs = verx.length();//顶点数 mgraph.Tedges = Tedges;//边数 //处理顶点 for (int i = 0; i < mgraph.Tvertexs; i++) { //转换 sstr.clear();//清空内存 sstr << verx[i];//写入一个顶点 sstr >> mgraph.vert[i].verxname;//获取一个顶点 mgraph.vert[i].number = i;//定义顶点编号 } //处理边 for (int i = 0; i < mgraph.Tedges; i++) { //转换 sstr.clear();//清空内存 sstr << weight[i];//写入权重 sstr >> mgraph.weight[i];//获取权重 sstr.clear(); sstr << edges[i][0];//获取一条边始点 sstr >> edge1; sstr.clear(); sstr << edges[i][1];//获取一条边终点 sstr >> edge2; int p1 = location(mgraph, edge1);//获取始点边下标 int p2 = location(mgraph, edge2);//获取终点边下标 mgraph.edages[p1][p2] = mgraph.weight[i];//写入该边权重 } } //输出邻接矩阵 void display() { cout << "Num & Vertex" << endl; //输出顶点下标以及顶点 for (int i = 0; i < mgraph.Tvertexs; i++) { cout << mgraph.vert[i].number << "\t";//下标 cout << mgraph.vert[i].verxname << endl;//顶点 } cout << "Matrix" << endl; for (int i = 0; i < mgraph.Tvertexs; i++) { for (int j = 0; j < mgraph.Tvertexs; j++) { //非无穷大则输出权值,否则输出无穷大标志 if (mgraph.edages[i][j] != INF) { cout << mgraph.edages[i][j] << "\t"; } else { cout << "∞" << "\t"; } } cout << endl; } } //矩阵存储转为邻接表 void MatTranToList() { Anode *p; fgraph = (FGraph *)malloc(sizeof(FGraph)); //邻接表组始边初始化为空 for (int i = 0; i < mgraph.Tvertexs; i++) { fgraph->adjList[i].firstAnode = NULL; } //头插法插入顶点以及权重信息 for (int i = 0; i < mgraph.Tvertexs; i++) { for (int j = mgraph.Tvertexs - 1; j >= 0; j--)//倒序 { //头插法 if (mgraph.edages[i][j] != INF) { p = (Anode *)malloc(sizeof(Anode)); p->weight = mgraph.edages[i][j];//权重 p->vesname = mgraph.vert[j].verxname;//顶点名称 p->nextAnode = fgraph->adjList[i].firstAnode;//链接后节点 fgraph->adjList[i].firstAnode = p;//链接当前节点 } } } fgraph->Tvertexs = mgraph.Tvertexs;//总顶点数 fgraph->Tedges = mgraph.Tedges;//总边数 } //输出邻接表 void disp() { cout << "List" << endl; cout << "vertex & weight" << endl; Anode *p; //输出顶点名称以及权重 for (int i = 0; i < fgraph->Tvertexs; i++) { p = fgraph->adjList[i].firstAnode;//指向首节点 while (p != NULL)//p不为空时循环输出下一节点 { cout << p->vesname << "&" << p->weight << ends; p = p->nextAnode; } cout << endl; } } //广度优先 void BfsOut() { cout << "BFS" << endl; InitVisited();//初始化遍历数组 BFS(fgraph, 0);//广度优先输出,从0开始 cout << endl; } //深度优先 void DfsOut() { cout << "DFS" << endl; InitVisited();//初始化遍历数组 DFS(fgraph, 0);//深度优先,从0开始 cout << endl; } private: MGraph mgraph;//邻接矩阵 FGraph *fgraph;//邻接表 string verx;//顶点 string weight;//权重 string edges[MAX_N];//边 int Tedges;//边数 stringstream sstr;//转换 int visited[MAX_N]; //搜索下标 int location(MGraph mg, char index) { for (int i = 0; i < mg.Tvertexs; i++) { if (mg.vert[i].verxname == index)//顶点名称匹配 { return i;//返回位置 } } return -1; } //深度优先 void DFS(FGraph *fg, int versname) { Anode *p; visited[versname] = 1;//定义为已遍历 cout << versname << ends;//输出顶点名称 p = fg->adjList[versname].firstAnode; while (p != NULL) { if (visited[p->vesname] == INF)//未访问 { DFS(fg, p->vesname);//递归遍历 } p = p->nextAnode;//下一条边 } } //广度优先 void BFS(FGraph *fg, int versname) { Anode *p; int queue[MAX_N], front = 0, rear = 0; int w; cout << versname << ends;//输出顶点名称 visited[versname] = 1;//定义为已遍历 rear = (rear + 1) % MAX_N;//尾加向后移动 queue[rear] = versname;//当前顶点名称为尾 while (front != rear)//非空 { front = (front + 1) % MAX_N;//头向后移动 w = queue[front];//记录暂定开始顶点名称 p = fgraph->adjList[w].firstAnode;//该顶点下一位 while (p != NULL) { if (visited[p->vesname] == INF)//未访问 { cout << p->vesname << ends;//输出 visited[p->vesname] = 1;//定义已访问 rear = (rear + 1) % MAX_N;//向后 queue[rear] = p->vesname;//从新赋值为当前顶点信息 } p = p->nextAnode;//下一条边 } } cout << endl; } }; int main() { Graph g; g.getInfo("data");//打开文件 g.CreateGraphMatrix();//创建图 g.display();//临接矩阵输出 g.MatTranToList();//邻接矩阵转换为邻接表 g.disp();//邻接表输出 g.DfsOut();//深度优先 g.BfsOut();//广度优先 return 0; }
<span style="font-size:18px;">测试结果:</span>
<span style="font-size:18px;"><img src="http://img.blog.csdn.net/20160102205650049?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" /> </span>
<span style="font-size:18px;"> </span>
相关文章推荐
- ChiMerge 算法
- 设计模式(13)-桥接模式
- saltstack
- 蓝懿iOS 技术交流和心得分享16.1.2
- UML类图关系
- Spring常用配置解析
- Spring常用配置解析
- 数据结构--队列-泛型OC&C++混编-泛型编程
- c语言中return,和exit的区别
- Linux下 目录 压缩 解压缩 打包
- Unity-Animator深入系列---录制与回放
- 两个队列实现一个栈
- OC(构造函数,分类等知识总结)
- android studio2.0解决办法 Plugin is too old, please update to a more recent version
- 实现客户端和服务器双向的防重放攻击
- 备忘
- 线段树模板
- 使用讯飞语音实现语音识别,朗读文字
- Java Web 跨平台 - 使用Apache Axis2引擎发布基于Java语言的WebService并跨平台调用实例
- Burp Suite抓包、截包和改包