添加kruskal算法:

  1. #ifndef GRAPH_H
  2. #define GRAPH_H
  3.  
  4. #include "Object.h"
  5. #include "SharedPointer.h"
  6. #include "Array.h"
  7. #include "DynamicArray.h"
  8. #include "LinkQueue.h"
  9. #include "LinkStack.h"
  10. #include "Sort.h"
  11.  
  12. namespace DTLib
  13. {
  14.  
  15. template < typename E >
  16. struct Edge : public Object
  17. {
  18. int b;
  19. int e;
  20. E data;
  21.  
  22. Edge(int i=-, int j=-)
  23. {
  24. b = i;
  25. e = j;
  26. }
  27.  
  28. Edge(int i, int j, const E& value)
  29. {
  30. b = i;
  31. e = j;
  32. data = value;
  33. }
  34.  
  35. bool operator == (const Edge<E>& obj)
  36. {
  37. return (b == obj.b) && (e == obj.e); //在这里不关注权值大小
  38. }
  39.  
  40. bool operator != (const Edge<E>& obj)
  41. {
  42. return !(*this == obj);
  43. }
  44.  
  45. bool operator < (const Edge<E>& obj)
  46. {
  47. return (data < obj.data);
  48. }
  49.  
  50. bool operator > (const Edge<E>& obj)
  51. {
  52. return (data > obj.data);
  53. }
  54. };
  55.  
  56. template < typename V, typename E >
  57. class Graph : public Object
  58. {
  59. protected:
  60. template < typename T >
  61. DynamicArray<T>* toArray(LinkQueue<T>& queue)
  62. {
  63. DynamicArray<T>* ret = new DynamicArray<T>(queue.length());
  64.  
  65. if( ret != NULL )
  66. {
  67. for(int i=; i<ret->length(); i++, queue.remove())
  68. {
  69. ret->set(i, queue.front());
  70. }
  71. }
  72. else
  73. {
  74. THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create ret object...");
  75. }
  76.  
  77. return ret;
  78. }
  79.  
  80. SharedPointer< Array<Edge<E> > > getUndirectedEdges()
  81. {
  82. DynamicArray<Edge<E>>* ret = NULL;
  83.  
  84. if( asUndirected() )
  85. {
  86. LinkQueue<Edge<E>> queue;
  87.  
  88. for(int i=; i<vCount(); i++)
  89. {
  90. for(int j=i; j<vCount(); j++)
  91. {
  92. if( isAdjacent(i, j) )
  93. {
  94. queue.add(Edge<E>(i, j, getEdge(i, j)));
  95. }
  96. }
  97. }
  98.  
  99. ret = toArray(queue);
  100. }
  101. else
  102. {
  103. THROW_EXCEPTION(InvalidOperationException, "This function is for undirected graph only...");
  104. }
  105.  
  106. return ret;
  107. }
  108.  
  109. int find(Array<int>& p, int v)
  110. {
  111. while( p[v] != -)
  112. {
  113. v = p[v];
  114. }
  115.  
  116. return v;
  117. }
  118. public:
  119. virtual V getVertex(int i) = ;
  120. virtual bool getVertex(int i, V& value) = ;
  121. virtual bool setVertex(int i, const V& value) = ;
  122. virtual SharedPointer< Array<int> > getAdjacent(int i) = ;
  123. virtual bool isAdjacent(int i, int j) = ;
  124. virtual E getEdge(int i, int j) = ;
  125. virtual bool getEdge(int i, int j, E& value) = ;
  126. virtual bool setEdge(int i, int j, const E& value) = ;
  127. virtual bool removeEdge(int i, int j) = ;
  128. virtual int vCount() = ;
  129. virtual int eCount() = ;
  130. virtual int OD(int i) = ;
  131. virtual int ID(int i) = ;
  132.  
  133. virtual int TD(int i)
  134. {
  135. return ID(i) + OD(i);
  136. }
  137.  
  138. bool asUndirected()
  139. {
  140. bool ret = true;
  141.  
  142. for(int i=; i<vCount(); i++)
  143. {
  144. for(int j=; j<vCount(); j++)
  145. {
  146. if( isAdjacent(i, j) )
  147. {
  148. ret = ret && isAdjacent(j, i) && (getEdge(i, j) == getEdge(j, i));
  149. }
  150. }
  151. }
  152.  
  153. return ret;
  154. }
  155.  
  156. SharedPointer< Array< Edge<E > > > prim(const E& LIMIT, const bool MINIUM = true) //参数为理论上的最大权值
  157. {
  158. LinkQueue< Edge<E> > ret;
  159.  
  160. if( asUndirected() )
  161. {
  162. DynamicArray<int> adjVex(vCount());
  163. DynamicArray<bool> mark(vCount());
  164. DynamicArray<E> cost(vCount());
  165. SharedPointer< Array<int> > aj = NULL;
  166. bool end = false;
  167. int v = ;
  168.  
  169. for(int i=; i<vCount(); i++)
  170. {
  171. adjVex[i] = -;
  172. mark[i] = false;
  173. cost[i] = LIMIT;
  174. }
  175.  
  176. mark[v] = true;
  177.  
  178. aj = getAdjacent(v);
  179.  
  180. for(int j=; j<aj->length(); j++)
  181. {
  182. cost[(*aj)[j]] = getEdge(v, (*aj)[j]);
  183. adjVex[(*aj)[j]] = v;
  184. }
  185.  
  186. for(int i=; (i<vCount()) && !end; i++)
  187. {
  188. E m = LIMIT;
  189. int k = -;
  190.  
  191. for(int j=; j<vCount(); j++)
  192. {
  193. if( !mark[j] && (MINIUM ? (cost[j] < m) : (cost[j] > m)))
  194. {
  195. m = cost[j];
  196. k = j;
  197. }
  198. }
  199.  
  200. end = (k == -);
  201.  
  202. if( !end )
  203. {
  204. ret.add(Edge<E>(adjVex[k], k, getEdge(adjVex[k], k)));
  205.  
  206. mark[k] = true;
  207.  
  208. aj = getAdjacent(k);
  209.  
  210. for(int j=; j<aj->length(); j++)
  211. {
  212. if( !mark[(*aj)[j]] && (MINIUM ? (getEdge(k, (*aj)[j]) < cost[(*aj)[j]]) : (getEdge(k, (*aj)[j]) > cost[(*aj)[j]])) )
  213. {
  214. cost[(*aj)[j]] = getEdge(k, (*aj)[j]);
  215. adjVex[(*aj)[j]] = k;
  216. }
  217. }
  218. }
  219. }
  220. }
  221. else
  222. {
  223. THROW_EXCEPTION(InvalidOperationException, "Prim operator is for undirected graph only...");
  224. }
  225.  
  226. if( ret.length() != (vCount() - ) )
  227. {
  228. THROW_EXCEPTION(InvalidOperationException, "No enough edge for prim operation...");
  229. }
  230.  
  231. return toArray(ret);
  232. }
  233.  
  234. SharedPointer< Array<Edge<E> > > kruskal(const bool MINMUM = true)
  235. {
  236. LinkQueue< Edge<E> > ret;
  237.  
  238. SharedPointer< Array< Edge<E> > > edges = getUndirectedEdges();
  239.  
  240. DynamicArray<int> p(vCount()); //前驱标记数组
  241.  
  242. for(int i=; i<p.length(); i++)
  243. {
  244. p[i] = -;
  245. }
  246.  
  247. Sort::Shell(*edges, MINMUM);
  248.  
  249. for(int i=; (i<edges->length()) && (ret.length() < (vCount() - )); i++)
  250. {
  251. int b = find(p, (*edges)[i].b);
  252. int e = find(p, (*edges)[i].e);
  253.  
  254. if( b != e )
  255. {
  256. p[e] = b;
  257.  
  258. ret.add((*edges)[i]);
  259. }
  260. }
  261.  
  262. if( ret.length() != (vCount() - ) )
  263. {
  264. THROW_EXCEPTION(InvalidOperationException, "No enough edges for Kruskal operation...");
  265. }
  266.  
  267. return toArray(ret);
  268. }
  269.  
  270. SharedPointer< Array<int> > BFS(int i)
  271. {
  272. DynamicArray<int>* ret = NULL;
  273.  
  274. if( ( <= i) && (i < vCount()) )
  275. {
  276. LinkQueue<int> q;
  277. LinkQueue<int> r;
  278. DynamicArray<bool> visited(vCount());
  279.  
  280. for(int i=; i<visited.length(); i++)
  281. {
  282. visited[i] = false;
  283. }
  284.  
  285. q.add(i);
  286.  
  287. while( q.length() > )
  288. {
  289. int v = q.front();
  290.  
  291. q.remove();
  292.  
  293. if( !visited[v] )
  294. {
  295. SharedPointer< Array<int> > aj = getAdjacent(v);
  296.  
  297. for(int j=; j<aj->length(); j++)
  298. {
  299. q.add((*aj)[j]);
  300. }
  301.  
  302. r.add(v);
  303.  
  304. visited[v] = true;
  305. }
  306. }
  307.  
  308. ret = toArray(r);
  309. }
  310. else
  311. {
  312. THROW_EXCEPTION(InvalidParameterException, "Index i is invalid...");
  313. }
  314.  
  315. return ret;
  316. }
  317.  
  318. SharedPointer< Array<int> > DFS(int i)
  319. {
  320. DynamicArray<int>* ret = NULL;
  321.  
  322. if( ( <= i) && (i < vCount()) )
  323. {
  324. LinkStack<int> s;
  325. LinkQueue<int> r;
  326. DynamicArray<bool> visited(vCount());
  327.  
  328. for(int j=; j<visited.length(); j++)
  329. {
  330. visited[j] = false;
  331. }
  332.  
  333. s.push(i);
  334.  
  335. while( s.size() > )
  336. {
  337. int v = s.top();
  338.  
  339. s.pop();
  340.  
  341. if( !visited[v] )
  342. {
  343. SharedPointer< Array<int> > aj = getAdjacent(v);
  344.  
  345. for(int j=aj->length() - ; j>=; j--)
  346. {
  347. s.push((*aj)[j]);
  348. }
  349.  
  350. r.add(v);
  351.  
  352. visited[v] = true;
  353. }
  354. }
  355.  
  356. ret = toArray(r);
  357. }
  358. else
  359. {
  360. THROW_EXCEPTION(InvalidParameterException, "Index i is invalid...");
  361. }
  362.  
  363. return ret;
  364. }
  365.  
  366. };
  367.  
  368. }
  369.  
  370. #endif // GRAPH_H

测试程序如下:

  1. #include <iostream>
  2. #include "MatrixGraph.h"
  3. #include "ListGraph.h"
  4.  
  5. using namespace std;
  6. using namespace DTLib;
  7.  
  8. template< typename V, typename E >
  9. Graph<V, E>& GraphEasy()
  10. {
  11. static MatrixGraph<, V, E> g;
  12.  
  13. g.setEdge(, , );
  14. g.setEdge(, , );
  15.  
  16. g.setEdge(, , );
  17. g.setEdge(, , );
  18.  
  19. g.setEdge(, , );
  20. g.setEdge(, , );
  21.  
  22. g.setEdge(, , );
  23. g.setEdge(, , );
  24.  
  25. g.setEdge(, , );
  26. g.setEdge(, , );
  27.  
  28. return g;
  29. }
  30.  
  31. template< typename V, typename E >
  32. Graph<V, E>& GraphComplex()
  33. {
  34. static ListGraph<V, E> g();
  35.  
  36. g.setEdge(, , );
  37. g.setEdge(, , );
  38.  
  39. g.setEdge(, , );
  40. g.setEdge(, , );
  41.  
  42. g.setEdge(, , );
  43. g.setEdge(, , );
  44.  
  45. g.setEdge(, , );
  46. g.setEdge(, , );
  47.  
  48. g.setEdge(, , );
  49. g.setEdge(, , );
  50.  
  51. g.setEdge(, , );
  52. g.setEdge(, , );
  53.  
  54. g.setEdge(, , );
  55. g.setEdge(, , );
  56.  
  57. g.setEdge(, , );
  58. g.setEdge(, , );
  59.  
  60. g.setEdge(, , );
  61. g.setEdge(, , );
  62.  
  63. g.setEdge(, , );
  64. g.setEdge(, , );
  65.  
  66. g.setEdge(, , );
  67. g.setEdge(, , );
  68.  
  69. g.setEdge(, , );
  70. g.setEdge(, , );
  71.  
  72. g.setEdge(, , );
  73. g.setEdge(, , );
  74.  
  75. g.setEdge(, , );
  76. g.setEdge(, , );
  77.  
  78. g.setEdge(, , );
  79. g.setEdge(, , );
  80.  
  81. return g;
  82. }
  83.  
  84. int main()
  85. {
  86. Graph<int, int>& g = GraphComplex<int, int>();
  87.  
  88. SharedPointer< Array< Edge<int> > > sa = g.kruskal();
  89.  
  90. int w = ;
  91.  
  92. for(int i=; i<sa->length(); i++)
  93. {
  94. w += (*sa)[i].data;
  95. cout << (*sa)[i].b << " " << (*sa)[i].e << " " << (*sa)[i].data << endl;
  96. }
  97.  
  98. cout << "Weight: " << w << endl;
  99.  
  100. return ;
  101. }

结果如下:

小结:

第七十七课 最小生成树(Kruskal)的更多相关文章

  1. python六十七课——网络编程(基础知识了解)

    网络编程: 什么是网络编程? 网络:它是一种隐形的媒介:可以将多台计算机使用(将它们连接到一起) 网络编程:将多台计算机之间可以相互通信了(做数据交互) 一旦涉及到网络编程,划分为两个方向存在,一方我 ...

  2. NeHe OpenGL教程 第四十七课:CG顶点脚本

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  3. NeHe OpenGL教程 第三十七课:卡通映射

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  4. NeHe OpenGL教程 第二十七课:影子

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  5. NeHe OpenGL教程 第十七课:2D图像文字

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  6. 第三百七十七节,Django+Xadmin打造上线标准的在线教育平台—apps目录建立,以及数据表生成

    第三百七十七节,Django+Xadmin打造上线标准的在线教育平台—apps目录建立,以及数据表生成 apps目录建立 我们创建一个apps目录,将所有的app放到apps目录里去,这样方便管理,也 ...

  7. centos Linux下磁盘管理 parted,df ,du,fdisk,partprobe,mkfs.ext4,mount,/etc/fstab,fsck,e2fsck,mk2efs,tmpfs ,nr_inodes, LVM,传统方式扩容文件系统 第七节课

    centos Linux下磁盘管理   parted,df ,du,fdisk,partprobe,mkfs.ext4,mount,/etc/fstab,fsck,e2fsck,mk2efs,tmpf ...

  8. “全栈2019”Java第七十七章:抽象内部类与抽象静态内部类详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  9. 模板——最小生成树kruskal算法+并查集数据结构

    并查集:找祖先并更新,注意路径压缩,不然会时间复杂度巨大导致出错/超时 合并:(我的祖先是的你的祖先的父亲) 找父亲:(初始化祖先是自己的,自己就是祖先) 查询:(我们是不是同一祖先) 路径压缩:(每 ...

随机推荐

  1. 微信小程序code 换取 session_key

    code 换取 session_key ​这是一个 HTTPS 接口,开发者服务器使用登录凭证 code 获取 session_key 和 openid.其中 session_key 是对用户数据进行 ...

  2. laravel的工厂模式数据填充:

    数据表post中的字段结构. database\factory\UserFactory.php $factory->define(App\Post::class,function (Faker ...

  3. laravel使用使用 Php Artisan Tinker 实现模型的增删改查

    tinker命令: php artisan tinker 查阅数据库数据: App\User::count(); App\User::where('username', 'samuel')->f ...

  4. Spring Boot + Spring Cloud 实现权限管理系统 (集成 Shiro 框架)

    Apache Shiro 优势特点 它是一个功能强大.灵活的,优秀开源的安全框架. 它可以处理身份验证.授权.企业会话管理和加密. 它易于使用和理解,相比Spring Security入门门槛低. 主 ...

  5. 过滤器 拦截器 登录login实例

    当请求来的时候,首先经过拦截器/过滤器,在经过一系列拦截器/拦截器处理后,再由再根据URL找到Servlet.执行servlet中的代码. 过滤器:按照过滤的对象类型的不同,可分为按资源名过滤和按请求 ...

  6. [HDU4585]Shaolin

    Problem 问你一个数的前驱和后继 Solution Treap模板题 Notice 注意输出那个人的编号 Code #include<cmath> #include<cstdi ...

  7. java-Object类的解析(持续更新)

    1.getClass()方法 public class Object { /*一个本地方法,具体是用C(C++)在DLL中实现的,然后通过JNI调用*/ private static native v ...

  8. Mysql 数据库意向锁意义

    锁:对 “某种范围” 的数据上 “某种锁”1.“某种范围”:行.表 2.“某种锁”2.1 共享锁Shared Locks(S锁)1.兼容性:加了S锁的记录,允许其他事务再加S锁,不允许其他事务再加X锁 ...

  9. SpringCloud调用服务示例

    SpringCloud調用服務示例. SpringCloud简介: Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务 ...

  10. 每天CSS学习之caption-side

    caption-side是CSS2的属性,其作用是规定标题的位置在表格的上面还是下面. 1.top:默认值,将表格标题定位在表格之上.如下例子: caption{ caption-side:top; ...