无向图相关算法基础(c++实现)
来源:互联网 发布:mac如何卸载office 编辑:程序博客网 时间:2024/05/17 09:09
前言
在《无向图相关算法基础(java实现)》的博文中,用java实现了无向图的基础算法,本文通过c++实现。
前文已经将无向图基础算法的概念描述的很清楚,本文不再累述,直接上代码。
代码
本文涉及到的类如下:
- Undigraph.h 无向图类,用于无向图的创建。
Undigraph.cpp - BreadthFirstSearch.h 广度优先类,提供广度优先算法及两点间最短路径算法。
BreadthFirstSearch.cpp - TestMain.cpp 主函数,用于测试。
以上类,在VS2008开发环境测试通过,具体代码如下:
Undigraph.h:
#ifndef Undigraph_H#define Undigraph_H/*-------------------------------------------------------------------------------------------------------------------------程序名称:Undigraph2016年12月 描述:创建无向图邻接链表数据结构//------------------------------------------------------------------------------------------------------------------------*//*------------------------------------------------------【头文件】---------------------------------------------------------描述:包含程序所依赖的头文件//------------------------------------------------------------------------------------------------------------------------*/#include <list> using namespace std;/*------------------------------------------------------【类声明】---------------------------------------------------------描述:无向图邻接链表类,用于创建无向图邻接链表数据结构//------------------------------------------------------------------------------------------------------------------------*/class Undigraph{ private: int verticals;//顶点个数 int edges;//边的个数 list<int> *AdjacencyGraph;//指向邻接链表的指针 public: /**/ Undigraph(int vertical);//构建函数,根据参数“vertical”构建邻接链表,类型为list<int>[vertical],vertical为顶点个数,此时list<int>都为空,调用AddEdge()函数添加边后,完成整个邻接链表的创建。 int GetVerticals();//返回顶点个数 int GetEdges();//返回边个数 void AddEdge(int verticalStart,int verticalEnd);//根据参数“verticalStart”、“verticalEnd”,在无向图中录入边数据,完成无向图的邻接链表数据结构。 list<int>* GetAdjacencyGraph(int vetical);//根据参数"vetical"返回该顶点的邻接表 void PrintGraph();//打印该无向图};#endif
Undigraph.cpp:
#include "Undigraph.h" /*------------------------------------------------------【Undigraph()构造函数】---------------------------------------------描述:根据参数“vertical”,创建邻接链表参数:1:int vertical(图的顶点个数)其它:执行该函数后,构建的数据结构如下: 0 1 2 3 4 5 6//-------------------------------------------------------------------------------------------------------------------------*/Undigraph::Undigraph(int vertical){ this->verticals = vertical; this->edges = 0; AdjacencyGraph = new list<int>[this->verticals];}/*------------------------------------------------------【GetVerticals() 函数】---------------------------------------------描述:返回图的顶点个数参数:返回值:图的顶点个数//-------------------------------------------------------------------------------------------------------------------------*/int Undigraph::GetVerticals(){ return verticals;}/*------------------------------------------------------【GetEdges() 函数】---------------------------------------------描述:返回图的边个数参数:返回值:图的边个数//-------------------------------------------------------------------------------------------------------------------------*/int Undigraph::GetEdges(){ return edges;}/*------------------------------------------------------【AddEdge()函数】---------------------------------------------描述:根据参数“verticalStart”、“verticalEnd”,创建邻接链表的边参数:1:int verticalStart(边的起始顶点) 2:int verticalEnd(边的结束顶点)其它:执行该函数8次,录入8条边后,构建的数据结构如下: 0->6->2->1->5 1->0 2->0 3->5->4 4->5->6->3 5->3->4->0 6->0->4至此,无向图邻接链表数据结构构建完毕//-------------------------------------------------------------------------------------------------------------------------*/void Undigraph::AddEdge(int verticalStart,int verticalEnd){ AdjacencyGraph[verticalStart].push_back(verticalEnd); AdjacencyGraph[verticalEnd].push_back(verticalStart); this->edges++;}/*------------------------------------------------------【GetAdjacencyGraph 函数】---------------------------------------------描述:根据参数"vetical",返回该顶点的邻接表参数:1:int vetical(顶点)返回值:与参数顶点对应的,邻接链表其它:例如输入参数“vetical”为0,则返回的list中的数据为list(6、2、1、5)//-------------------------------------------------------------------------------------------------------------------------*/list<int>* Undigraph::GetAdjacencyGraph(int vetical){ return &AdjacencyGraph[vetical];}/*------------------------------------------------------【PrintGraph 函数】---------------------------------------------描述:打印图结构,适用于控制台程序参数:返回值:其它:调用后,将在cmd窗口输出图的结构图,该函数用于测试,对逻辑无影响//-------------------------------------------------------------------------------------------------------------------------*/void Undigraph::PrintGraph(){ printf("无向图邻接链表数据结构如下:\n"); for(int i=0;i<this->verticals;i++) { printf("%d->",i); for(list<int>::iterator j = this->AdjacencyGraph[i].begin();j!=AdjacencyGraph[i].end();j++) { printf("%d->",*j); } printf("\n"); }}
BreadthFirstSearch.h:
#ifndef BreadthFirstSearch_H#define BreadthFirstSearch_H//-------------------------------------------------------------------------------------------------------------------------//程序名称:BreadthFirstSearch//2016年12月 //描述:广度优先遍历,两点间最短路径//-------------------------------------------------------------------------------------------------------------------------//------------------------------------------------------【头文件】---------------------------------------------------------//描述:包含程序所依赖的头文件//-------------------------------------------------------------------------------------------------------------------------#include <stack> #include <queue>#include "Undigraph.h"using namespace std;//------------------------------------------------------【类声明】---------------------------------------------------------//描述:基于类“Undigraph”构建的无向图邻接链表,实现广度优先遍历、两点间最短路径//-------------------------------------------------------------------------------------------------------------------------class BreadthFirstSearch{private: bool *marked;//布尔类型数组,用于记录顶点是否被访问,true代表已经被访问,false代表未被访问 int *edgeTo;//整形数组,用于记录起点到终点所有的路径,最终根据该数组生成两点间最短路径 int sourceVetical;//起始顶点 void bfs(Undigraph g,int s);//广度优先遍历public: BreadthFirstSearch(Undigraph g,int s);//构造函数 bool HasPathTo(int v);//根据参数"v",判断起始顶点到该顶点是否有路径 stack<int>* PathTo(int v);//返回起始顶点“sourceVetical”到顶点“V”的最短路径 void printEdgeToAndMarked();//打印数组edgeTo和marked内容。};#endif
BreadthFirstSearch.cpp:
#include "BreadthFirstSearch.h"/*---------------------------------------------【BreadthFirstSearch()构造函数】---------------------------------------------描述:根据参数"Undigraph g"、"int s",创建广度优先遍历需要的布尔、整型数组。参数:1:Undigraph g(无向图对象) 2:int s(最短路径的起始点)其它:执行该函数后,构建的数据结构如下: 1、起始顶点为"0" 2、布尔、整型数组如下: marked 0|false edgeTo 0|65535 1|false 1|65535 2|false 2|65535 3|false 3|65535 4|false 4|65535 5|false 5|65535 6|false 6|65535 3、edgeTo整型数组用65535代表无穷大,代表无数据,因为有的时候顶点会为“0”,所以用无穷大代表无数据---------------------------------------------------------------------------------------------------------------------------*/BreadthFirstSearch::BreadthFirstSearch(Undigraph g,int s){ marked = new bool[g.GetVerticals()];//创建布尔型数组 edgeTo = new int[g.GetVerticals()];//创建整型数组 for(int i = 0;i<g.GetVerticals();i++)//数组付初始值 { marked[i] = false; edgeTo[i] = 0xFFFF; } this->sourceVetical = s;//获得起始顶点 bfs(g,s);//调用广度优先函数}/*---------------------------------------------【bfs()函数】---------------------------------------------描述:根据参数"Undigraph g"、"int s",对图进行广度优先遍历并填充edgeTo整型数组。参数:1:Undigraph g(无向图对象) 2:int s(最短路径的起始点)其它:执行该函数后,构建的数据结构如下: 1、起始顶点为"0" 2、布尔、整型数组如下: marked 0|true edgeTo 0|65535 1|ture 1|0 2|ture 2|0 3|ture ->3|5 4|ture 4|6 5|ture ->5|0 6|ture 6|0 3、程序执行后,数组edgeTo得到的是0到各个顶点的路径。如果所示,通过edgeTo[]数组即可得到0到3的路径为0->5->3---------------------------------------------------------------------------------------------------------------------------*/void BreadthFirstSearch::bfs(Undigraph g,int s){ queue<int>* q = new queue<int>();//创建队列 marked[s] = true;//将顶点在数组marked中设置为true,表示已访问过 q->push(s);//将顶点放入队列 while(q->size()!=0) { int v = q->front();//从队列中取出一个值 q->pop();//并将该值弹出队列 for each(int w in *g.GetAdjacencyGraph(v))//根据该值获得邻接链表。例如,如果V=0,则返回的邻接链表list为list(6,2,1,5),并对list中每个值做for each中的操作 { if(!marked[w])//如果该值没有被访问过。 { edgeTo[w] = v;//将该值对应的边添入edgeTo数组 marked[w] = true;//标记该值已经访问过 q->push(w);//将该值放入队列 } } }}/*------------------------------------------------【HasPathTo()函数】---------------------------------------------------描述:起始点到顶点“v”之间是否有路径参数:1:int v(任意顶点)返回值:true(有路径),false(无路径)---------------------------------------------------------------------------------------------------------------------------*/bool BreadthFirstSearch::HasPathTo(int v){ return marked[v];}/*------------------------------------------------【PathTo()函数】---------------------------------------------------描述:获得起始点到顶点“v”的路径参数:1:int v(任意顶点)返回值:stack<int>,存放两点间路径,例如: stack<int>: 0|0 1|5 2|3 存放的是路径0->5->3,既起始点0到终点3的路径---------------------------------------------------------------------------------------------------------------------------*/stack<int>* BreadthFirstSearch::PathTo(int v){ if(!HasPathTo(v))//判断两点之间是否有路径 { return NULL; } stack<int>* path = new stack<int>();//创建栈,用于存储路径 for(int x = v; x!=sourceVetical; x=edgeTo[x])//该循环用于创建路径 { path->push(x); } path->push(sourceVetical); return path;}/*----------------------------------------【printEdgeToAndMarked()函数】------------------------------------------------描述:打印数组marked与edgeTo的内容其它:该函数是测试用的函数,与具体业务逻辑无关---------------------------------------------------------------------------------------------------------------------------*/void BreadthFirstSearch::printEdgeToAndMarked(){ printf("edgeTo[]数组内容:\n"); for(int i=0;i<7;i++) { printf("%d:%d\n",i,edgeTo[i]); } printf("marked[]数组内容:\n"); for(int i=0;i<7;i++) { if(marked[i]) { printf("%d:%s\n",i,"true"); }else { printf("%d:%s\n",i,"false"); } }}
TestMain.cpp:
#include <stdio.h>#include "Undigraph.h"//无向图#include"DepthFirstPaths.h"//深度优先遍历#include"BreadthFirstSearch.h"//广度优先遍历/* 无向图邻接表: 无向图: 0->6->2->1->5 0-------------6 1->0 |\ \ | 2->0 | 1 2 | 3->5->4 | 3 | 4->5->6->3 | / \ | 5->3->4->0 | / \ | 6->0->4 | / \ | | / \ | | / \ | |/ \| 5-------------4 */void main(){ /*------------------------------------------------------无向图初始化----------------------------------------------------------------*/ Undigraph *g = new Undigraph(7);//7个顶点 g->AddEdge(0,6);//输入边数据,不要重复输入边的数据 g->AddEdge(0,2); g->AddEdge(0,1); g->AddEdge(0,5); g->AddEdge(4,3); g->AddEdge(4,5); g->AddEdge(3,5); g->AddEdge(6,4); g->PrintGraph();//打印图 /*-----------------------------------------------------广度优先遍历-----------------------------------------------------------------*/ BreadthFirstSearch* bfs = new BreadthFirstSearch(*g,0);//初始化广度优先,g为邻接表,0为起始顶点。 stack<int> *s = bfs->PathTo(3);//获得0到3的最小路径,并存储在栈s中 printf("广度优先路径开始:"); while(!s->empty())//打印最小路径 { printf("%d->",s->top()); s->pop(); } printf("结束:\n"); bfs->printEdgeToAndMarked();//打印数组edgeTo与marked的内容 /*-----------------------------------------------------深度优先遍历----------------------------------------------------------------- DepthFirstPaths *dfs = new DepthFirstPaths(*g,0); stack<int> *ss = dfs->PathTo(3); printf("深度优先路径开始:"); while(!ss->empty())//打印最小路径 { printf("%d->",ss->top()); ss->pop(); } printf("结束:\n"); */ /*------------------------------------------------------清除资源-------------------------------------------------------------------*/ delete g; delete bfs; delete s; //delete dfs; //delete ss;}
执行效果
0 0
- 无向图相关算法基础(java实现)
- 无向图相关算法基础(c++实现)
- 五、 无向图相关算法基础
- 浅谈算法和数据结构----无向图相关算法基础
- 数据结构(11)无向图相关算法基础
- 无向图最短路径算法(C#)实现
- 浅谈算法和数据结构(12):无向图相关算法基础
- 浅谈算法和数据结构: 十二 无向图相关算法基础
- 浅谈算法和数据结构: 十二 无向图相关算法基础
- 浅谈算法和数据结构: 十二 无向图相关算法基础
- 浅谈算法和数据结构: 十二 无向图相关算法基础
- 浅谈算法和数据结构: 十二 无向图相关算法基础
- 浅析数据结构与算法12--无向图相关算法基础
- 无向图的最小生成树算法的C程序实现代码(Prim算法)
- 无向图最小割的相关算法及其延伸
- kruskal算法 求最小生成树(邻接表 无向图) C实现
- 无向图的DFS和BFS算法实现
- 无向图的最短路径算法(队列实现 )
- eclipse中怎么修改所复制的web项目的部署名字
- universal-image-loader使用参考
- 最长递增子序列
- spring-boot项目部署到tomcat容器中
- 实体零售,为什么干不过电商?
- 无向图相关算法基础(c++实现)
- HTC开门效果
- Android的各种Drawable讲解
- 0.0
- eclipse里maven install时,报错提示jdk为无效的目标版本:1.7
- VMwarea安装centos7.0图解
- Sqoop使用实战
- 共同学习Java源代码--数据结构--Set接口
- 理解 openstack 中的 service catalog