当前位置: 首页 > wzjs >正文

深圳哪家网站建设服务好软文写作范文500字

深圳哪家网站建设服务好,软文写作范文500字,wordpress 显示excel,推广平台开户代理✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】【高阶数据结构】 目录 1、图的存储结构 1.1、邻接表 1.1.1、边的结构 1.1.2、图的基本结构 1.1.3、图的创建 1.1.4、获取顶点下…

个人主页: 熬夜学编程的小林

💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】【Linux系统编程】【高阶数据结构】

目录

1、图的存储结构

1.1、邻接表

1.1.1、边的结构

1.1.2、图的基本结构

1.1.3、图的创建

1.1.4、获取顶点下标

1.1.5、添加边

1.1.6、打印

1.1.7、测试一

1.1.8、测试二

2、图的遍历

2.1、图的广度优先遍历

2.2、图的深度优先遍历 


1、图的存储结构

1.1、邻接表

邻接表使用数组表示顶点的集合,使用链表表示边的关系

1. 无向图邻接表存储 

注意无向图中同一条边在邻接表中出现了两次。如果想知道顶点vi的度,只需要知道顶点vi边链表集合中结点的数目即可。 

2. 有向图邻接表存储

注意:有向图中每条边在邻接表中只出现一次,与顶点vi对应的邻接表所含结点的个数,就是该顶点的出度,也称出度表,要得到vi顶点的入度,必须检测其他所有顶点对应的边链表,看有多少边顶点的dst取值是i。 

1.1.1、边的结构

1、邻接表使用链表来存储边之间的关系,因此成员需要next指针,除此之外还需要起始点(此处可以省略,因为使用目标点即可实现图)目标点权值

2、此处还需要实现一个有参构造函数参数包括目标点下标和权值

3、权值需要使用类型模板参数

template<class W>
struct Edge
{// int _srci; // 起始点,入边使用int _dsti;    // 目标点下标,出边使用W _w;        // 权值Edge<W>* _next;Edge(size_t dsti, const W& w):_dsti(dsti),_w(w),_next(nullptr){}
};

1.1.2、图的基本结构

1、使用邻接表存储图的基本结构与使用邻接矩阵存储图的基本结构类似,邻接表同样的使用模板实现,但是无需表示无穷大的非类型模板参数,因为此处为链表结构,添加边的时候才需要new新的结点

2、成员变量包括顶点集合,顶点与下标的映射关系和领接表

template<class V, class W, bool Direction = false>
class Graph
{typedef Edge<W> Edge;
public:// ...
private:vector<V> _vertexs;     // 顶点集合map<V, int> _vIndexMap; // 顶点映射下标vector<Edge*> _tables;  // 邻接表
};

1.1.3、图的创建

图的创建与邻接矩阵一样,使用手动添加边的方式创建,即实现一个有参构造(参数包含定带你集合以及顶点个数)

Graph(const V* a, size_t n)
{_vertexs.reserve(n);for (size_t i = 0; i < n; i++){_vertexs.push_back(a[i]);_vIndexMap[a[i]] = i;}_tables.resize(n, nullptr);
}

注意:此处的邻接表只需开辟一层空间,因为当添加边的时候,我们会new新的结点。

1.1.4、获取顶点下标

顶点与下标的映射存储在map中,获取顶点对应的下标只需要在map中进行查找即可,找到则返回下标,没找到则抛异常(为了编译通过,返回-1)。

// 根据顶点获取下标
size_t GetVertexIndex(const V& v)
{auto it = _vIndexMap.find(v);if (it != _vIndexMap.end()){return it->second;}else{throw invalid_argument("顶点不存在");return -1;}
}

1.1.5、添加边

1、参数为起始顶点,结束顶点和权值,还需注意有向与无向图

2、添加边的思想先获取顶点对应的下标,然后将新的结点头插到邻接表中,如果是无向图则需双向存储

void AddEdge(const V& src, const V& dst, const W& w)
{size_t srci = GetVertexIndex(src);size_t dsti = GetVertexIndex(dst);// 1 -> 2 Edge* eg = new Edge(dsti, w);// 将Edge头插到邻接表eg->_next = _tables[srci];_tables[srci] = eg;// 无向图 2 -> 1if (Direction == false){Edge* eg = new Edge(srci, w);// 将Edge头插到邻接表eg->_next = _tables[dsti];_tables[dsti] = eg;}
}

1.1.6、打印

打印的方式可以根据自己需求打印,此处打印下标与顶点的映射关系和邻接表为了让打印更美观,将邻接表打印成   顶点[下标]->[顶点,下标,权值]...  的形式

void Print()
{// 顶点 下标 -> 顶点值for (size_t i = 0; i < _vertexs.size(); i++){cout << "[" << i << "]->" << _vertexs[i] << endl;}cout << endl;// 邻接表for (size_t i = 0; i < _tables.size(); i++){// 顶点[下标]->[顶点,下标,权值]...cout << _vertexs[i] << "[" << i << "]->";Edge* cur = _tables[i];while (cur){cout << "[" << _vertexs[cur->_dsti] << "," << cur->_dsti << "," << cur->_w << "]->";cur = cur->_next;}cout << "nullptr" << endl;}
}

1.1.7、测试一

顶点值为char类型。

void TestGraph1()
{Graph<char, int, true> g("0123", 4);g.AddEdge('0', '1', 1);g.AddEdge('0', '3', 4);g.AddEdge('1', '3', 2);g.AddEdge('1', '2', 9);g.AddEdge('2', '3', 8);g.AddEdge('2', '1', 5);g.AddEdge('2', '0', 3);g.AddEdge('3', '2', 6);g.Print();
}

构造函数 

添加边

打印结果

1.1.8、测试二

顶点值为string类型。

测试代码 

void TestGraph2()
{string a[] = { "张三", "李四", "王五", "赵六" };Graph<string, int, true> g1(a, 4);g1.AddEdge("张三", "李四", 100);g1.AddEdge("张三", "王五", 200);g1.AddEdge("王五", "赵六", 30);g1.Print();
}

打印结果 

2、图的遍历

注意:此处的遍历操作都是基于邻接矩阵进行遍历的。

给定一个图G和其中任意一个顶点v0,从v0出发,沿着图中各边访问图中的所有顶点,且每个顶点仅被遍历一次"遍历"即对结点进行某种操作的意思

2.1、图的广度优先遍历

如何防止节点被重复遍历?

我们可以创建一个标记容器成员类型为bool类型,访问过则将值设置为true,默认为false。 

广度优先遍历思想:

与二叉树的层序遍历类似,需要借助队列先将第一个值入队列,出队列的同时把邻接顶点入队,直到队列为空则遍历结束,具体步骤如下:

  • 1、获取顶点对应的下标
  • 2、创建队列和标记容器
  • 3、入队
  • 4、队列不为空则遍历
    • 4.1、打印队头
    • 4.2、将front的邻接顶点入队
      • 有效边且标志位为false则入队

遍历代码 

// 根据顶点进行广度优先遍历,使用队列+标记容器
void BFS(const V& src)
{// 1.获取顶点对应的下标size_t srci = GetVertexIndex(src);// 2.创建队列和标记容器queue<int> q;vector<bool> visited(_vertexs.size(),false); // 默认false可以访问// 3.入队q.push(srci);visited[srci] = true; // 不能访问size_t n = _vertexs.size();// 4.队列不为空则遍历while (!q.empty()){// 打印队头int front = q.front();q.pop();cout << front << ":" << _vertexs[front] << endl;// 将front的邻接顶点入队for (size_t i = 0; i < n; i++){// 有效边且标志位为false则入队if (_matrix[front][i] != MAX_W && !visited[i]){q.push(i);visited[i] = true;}}}cout << endl;
}

测试代码

void TestBDFS()
{string a[] = { "张三", "李四", "王五", "赵六", "周七" };Graph<string, int> g1(a, sizeof(a) / sizeof(string));g1.AddEdge("张三", "李四", 100);g1.AddEdge("张三", "王五", 200);g1.AddEdge("王五", "赵六", 30);g1.AddEdge("王五", "周七", 30);g1.Print();g1.BFS("张三");
}

结构及打印结果

遍历结果

上面确实实现了广度优先遍历,但是能不能像二叉树的层序遍历一样,打印每一层呢?

可以的。

与二叉树打印每一层类型,我们可以创建一个记录队列元素个数的变量,一次打印队列元素个数个,打印完一层之后更新这个值

一层层打印 

// 广度优先遍历(一层层打印)
void BFS(const V& src)
{// 1.获取顶点对应的下标size_t srci = GetVertexIndex(src);// 2.创建队列和标记容器queue<int> q;vector<bool> visited(_vertexs.size(), false); // 默认false可以访问// 3.入队q.push(srci);visited[srci] = true; // 不能访问int levelSize = 1;size_t n = _vertexs.size();// 4.队列不为空则遍历while (!q.empty()){// 一层层打印,一次打印队列个数个for (int i = 0; i < levelSize; i++){// 打印队头int front = q.front();q.pop();cout << front << ":" << _vertexs[front] << endl;// 将front的邻接顶点入队for (size_t i = 0; i < n; i++){// 有效边且标志位为false则入队if (_matrix[front][i] != MAX_W && !visited[i]){q.push(i);visited[i] = true;}}}cout << endl;levelSize = q.size();}
}

遍历结果 

2.2、图的深度优先遍历 

深度优先遍历思想: 

与二叉树的前序遍历类似,但是此处需要使用标记容器,因此需要实现一个子函数具体步骤如下:

  • 1、获取顶点对应的下标
  • 2、创建标记容器
  • 3、调用子函数

子函数思想:

  • 1、打印该位置的值并将该位置的标记位设置为true(不能再访问)
  • 2、找一个该位置相邻的且没有访问过的点深度遍历

代码实现 

void _DFS(size_t srci, vector<bool>& visited)
{// 下标:顶点值cout << srci << ":" << _vertexs[srci] << endl;visited[srci] = true; // 不能再访问// 找一个scri相邻的且没有访问过的点,深度遍历for (size_t i = 0; i < _vertexs.size(); i++){if (_matrix[srci][i] != MAX_W && !visited[i]){_DFS(i, visited);}}
}
void DFS(const V& src)
{size_t srci = GetVertexIndex(src);vector<bool> visited(_vertexs.size(), false);_DFS(srci, visited);
}

运行结果

http://www.dtcms.com/wzjs/474483.html

相关文章:

  • 无锡网站建设外包优势互联网营销培训课程
  • 四川微信网站建设seo网站查询
  • 类似稿定设计的软件有哪些网站优化及推广
  • 织梦企业网站管理系统2020国内搜索引擎排行榜
  • 湖南网站建设公司排行榜微信推广怎么做
  • 专业的移动网站建设公司四川百度推广和seo优化
  • 做公司网站用哪个空间好seo推广人员
  • 郑州手机网站建设html简单网页设计作品
  • 做app 的模板下载网站有哪些seo软件开发
  • 企业网站建设费是无形资产吗外贸企业网站设计公司
  • 网站建设方案对比百度seo引流
  • 长沙做网站优化磁力猫torrent kitty
  • 仿新闻网站源码百度seo点击
  • 广州 Wix网站开发杭州网站推广与优化
  • 软件开发项目文档怎么写seo站长常用工具
  • 广州网站制作工作室无锡网站优化公司
  • 网站建设包括哪些服务网络推广工具有哪些
  • 国内做的好看的网站刷推广链接的网站
  • 泽成seo网站排名怎么发布信息到百度
  • 上海做网站公司有哪些技成培训网
  • wordpress 家庭照片360seo排名点击软件
  • 学校网站的服务器公司营销网站建设
  • 山西大同网站建设哪家好国际重大新闻
  • 上海外贸网站google建站百度搜索排名
  • 个人网站界面模板百度收录申请入口
  • 武汉平面设计个人博客seo
  • 网站建设网页设计案例如何制作网页
  • 带搜索网站建设视频教程百度广告太多
  • dedecms 网站搬家徐州做网站的公司
  • 网站里自已的微信联系如何做软文营销案例分析