第七十五课 图的遍历(DFS)
添加DFS函数:
#ifndef GRAPH_H
#define GRAPH_H #include "Object.h"
#include "SharedPointer.h"
#include "Array.h"
#include "DynamicArray.h"
#include "LinkQueue.h"
#include "LinkStack.h" namespace DTLib
{ template < typename E >
struct Edge : public Object
{
int b;
int e;
E data; Edge(int i=-, int j=-)
{
b = i;
e = j;
} Edge(int i, int j, const E& value)
{
b = i;
e = j;
data = value;
} bool operator == (const Edge<E>& obj)
{
return (b == obj.b) && (e == obj.e); //在这里不关注权值大小
} bool operator != (const Edge<E>& obj)
{
return !(*this == obj);
}
}; template < typename V, typename E >
class Graph : public Object
{
protected:
template < typename T >
DynamicArray<T>* toArray(LinkQueue<T>& queue)
{
DynamicArray<T>* ret = new DynamicArray<T>(queue.length()); if( ret != NULL )
{
for(int i=; i<ret->length(); i++, queue.remove())
{
ret->set(i, queue.front());
}
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create ret object...");
} return ret;
}
public:
virtual V getVertex(int i) = ;
virtual bool getVertex(int i, V& value) = ;
virtual bool setVertex(int i, const V& value) = ;
virtual SharedPointer< Array<int> > getAdjacent(int i) = ;
virtual E getEdge(int i, int j) = ;
virtual bool getEdge(int i, int j, E& value) = ;
virtual bool setEdge(int i, int j, const E& value) = ;
virtual bool removeEdge(int i, int j) = ;
virtual int vCount() = ;
virtual int eCount() = ;
virtual int OD(int i) = ;
virtual int ID(int i) = ;
virtual int TD(int i)
{
return ID(i) + OD(i);
} SharedPointer< Array<int> > BFS(int i)
{
DynamicArray<int>* ret = NULL; if( ( <= i) && (i < vCount()) )
{
LinkQueue<int> q;
LinkQueue<int> r;
DynamicArray<bool> visited(vCount()); for(int i=; i<visited.length(); i++)
{
visited[i] = false;
} q.add(i); while( q.length() > )
{
int v = q.front(); q.remove(); if( !visited[v] )
{
SharedPointer< Array<int> > aj = getAdjacent(v); for(int j=; j<aj->length(); j++)
{
q.add((*aj)[j]);
} r.add(v); visited[v] = true;
}
} ret = toArray(r);
}
else
{
THROW_EXCEPTION(InvalidParameterException, "Index i is invalid...");
} return ret;
} SharedPointer< Array<int> > DFS(int i)
{
DynamicArray<int>* ret = NULL; if( ( <= i) && (i < vCount()) )
{
LinkStack<int> s;
LinkQueue<int> r;
DynamicArray<bool> visited(vCount()); for(int j=; j<visited.length(); j++)
{
visited[j] = false;
} s.push(i); while( s.size() > )
{
int v = s.top(); s.pop(); if( !visited[v] )
{
SharedPointer< Array<int> > aj = getAdjacent(v); for(int j=aj->length() - ; j>=; j--)
{
s.push((*aj)[j]);
} r.add(v); visited[v] = true;
}
} ret = toArray(r);
}
else
{
THROW_EXCEPTION(InvalidParameterException, "Index i is invalid...");
} return ret;
}
}; } #endif // GRAPH_H
测试程序如下:
#include <iostream>
#include "BTreeNode.h"
#include "ListGraph.h"
#include "MatrixGraph.h" using namespace std;
using namespace DTLib; int main()
{
MatrixGraph<, char, int> g;
const char* VD = "ABEDCGFHI"; for(int i=; i<; i++)
{
g.setVertex(, VD[i]);
} g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); SharedPointer< Array<int> > sa = g.DFS(); for(int i=; i<sa->length(); i++)
{
cout << (*sa)[i] << " ";
} cout << endl; return ;
}
结果如下:
深度优先的思想就是二叉树的先序遍历思想。
递归版的深入优先算法如下:
#include <iostream>
#include "BTreeNode.h"
#include "ListGraph.h"
#include "MatrixGraph.h" using namespace std;
using namespace DTLib; template < typename V, typename E>
void DFS(Graph<V, E>& g, int v, Array<bool>& visited)
{
if( ( <= v) && (v < g.vCount()) )
{
cout << v << endl; visited[v] = true; SharedPointer< Array<int> > aj = g.getAdjacent(v); for(int i=; i<aj->length(); i++)
{
if( !visited[(*aj)[i]] )
{
DFS(g, (*aj)[i], visited);
}
}
}
else
{
THROW_EXCEPTION(InvalidParameterException, "Index v is invalid...");
}
} template < typename V, typename E >
void DFS(Graph<V, E>& g, int v)
{
DynamicArray<bool> visited(g.vCount()); for(int i=; i<visited.length(); i++)
{
visited[i] = false;
} DFS(g, v, visited);
} int main()
{
MatrixGraph<, char, int> g;
const char* VD = "ABEDCGFHI"; for(int i=; i<; i++)
{
g.setVertex(, VD[i]);
} g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); g.setEdge(, , );
g.setEdge(, , ); SharedPointer< Array<int> > sa = g.DFS(); for(int i=; i<sa->length(); i++)
{
cout << (*sa)[i] << " ";
} cout << endl; DFS(g, ); return ;
}
结果如下:
小结:
第七十五课 图的遍历(DFS)的更多相关文章
- 第七十四课 图的遍历(BFS)
广度优先相当于对顶点进行分层,层次遍历. 在Graph.h中添加BFS函数: #ifndef GRAPH_H #define GRAPH_H #include "Object.h" ...
- NeHe OpenGL教程 第四十五课:顶点缓存
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- NeHe OpenGL教程 第三十五课:播放AVI
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- NeHe OpenGL教程 第十五课:纹理图形字
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- 第三百七十五节,Django+Xadmin打造上线标准的在线教育平台—创建课程机构app,在models.py文件生成3张表,城市表、课程机构表、讲师表
第三百七十五节,Django+Xadmin打造上线标准的在线教育平台—创建课程机构app,在models.py文件生成3张表,城市表.课程机构表.讲师表 创建名称为app_organization的课 ...
- NeHe OpenGL教程 第二十五课:变形
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- PMP十五至尊图(第六版)
PMP(Project Management Professinoal)项目经理专业资格认证,由美国项目管理学会PMI(Project Management Institute)发起并组织的一种资格认 ...
- “全栈2019”Java第七十五章:内部类持有外部类对象
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 孤荷凌寒自学python第七十五天开始写Python的第一个爬虫5
孤荷凌寒自学python第七十五天开始写Python的第一个爬虫5 (完整学习过程屏幕记录视频地址在文末) 今天在上一天的基础上继续完成对我的第一个代码程序的书写. 直接上代码.详细过程见文末屏幕录像 ...
随机推荐
- Notes for 'Making elephants fly'
1. 技术陷阱:应是需求导向, 而不是技术导向. 2. 时机最重要:而不是创造力,团队,客户,产品,或技术. 3. 模仿:能模仿就模仿,不能模仿就创新.巧匠摹形,大师窃意. good artists ...
- JavaScript基础(四)
十六.client.offset.scroll系列 1.client系列 代码如下: <!DOCTYPE html> <html> <head> <meta ...
- #pragma 处理警告 clang diagnostic 的使用
首先#pragma在本质上是声明,常用的功能就是注释,尤其是给Code分段注释:而且它还有另一个强大的功能是处理编译器警告,但却没有上一个功能用的那么多. clang diagnostic 是#pra ...
- MongoDB,无模式文档型数据库简介
MongoDB的名字源自一个形容词humongous(巨大无比的),在向上扩展和快速处理大数据量方面,它会损失一些精度,在旧金山举行的MondoDB大会上,Merriman说:“你不适宜用它来处理复杂 ...
- redis事件监听及在订单系统中的使用
https://blog.csdn.net/qq_37334135/article/details/77717248 通常在网上买好物品,或者说手机扫码后,点击付款,这时就会向后台发送请求,生成订单信 ...
- Android 常用动画
一.动画类型 Android的animation由四种类型组成:alpha.scale.translate.rotate XML配置文件中 alpha :渐变透明度动画效果 scale :渐变尺寸伸缩 ...
- 一篇文章有若干行,以空行作为输入结束的条件。统计一篇文章中单词the(不管大小写,单词the是由空格隔开的)的个数。
#include <iostream>using namespace std; int k = 0;int n = 0;int main() { char c; char a[1000]; ...
- @Configuration的使用 和作用
1从spring4.0以后,@Spring boot Application就包含了@ComponentScan,@ComponentScan就不用写了 2@MapperScan(basePackag ...
- linux下free命令详解
free 命令显示系统内存的使用情况,包括物理内存.交换内存(swap)和内核缓冲区内存. 如果加上 -h 选项,输出的结果会友好很多: 有时我们需要持续的观察内存的状况,此时可以使用 -s 选项并指 ...
- learning ddr mode register MR3