Geeks Union-Find Algorithm Union By Rank and Path Compression 图环算法
相同是查找一个图是否有环的算法,可是这个算法非常牛逼,构造树的时候能够达到O(lgn)时间效率。n代表顶点数
原因是依据须要缩减了树的高度,也叫压缩路径(Path compression),名字非常高深,只是事实上不难理解,简单来说就是每次查找一个节点的时候,都把这一路径中的全部节点都赋予根节点作为路径。
原文没指出的地方:
也由于须要压缩,所以初始化的时候注意,不能如前面简单有用Union Find的算法那样初始化全部顶点的父母节点为-1,应该是初始化全部节点的父母节点为本身(自己生殖自己?),然后就方便递归的时候一律能够返回这个跟节点了。
当然事实上初始化为-1也是能够的,只是须要额外代码处理一下,也不难。
最后能够參考原文:http://www.geeksforgeeks.org/union-find-algorithm-set-2-union-by-rank/
#pragma once
#include <iostream> class UnionFindUnionByRank
{
struct Edge
{
int src, des;
}; struct Graph
{
int V, E;
Edge *edges;
Graph(int v, int e) : V(v), E(e)
{
edges = new Edge[e];
}
~Graph()
{
if (edges) delete [] edges;
}
}; struct subSet
{
int parent, rank;
}; int find(subSet *subs, int i)
{
//由于要压缩,所以不能使用-1作为根的标志了
if (subs[i].parent != i)
{
//Union by rank: attach smaller rank tree to high rank tree. It is so simple, but very hard to create it totally by ourself, so it's good to stand on the shoulder of the giant.
subs[i].parent = find(subs, subs[i].parent);
}
return subs[i].parent;//由于假设-1作为根标志,那么这里就要返回i,就达不到压缩的效果了,而是应该返回parent,一层一层递归回上一层。
} void unionTwo(subSet *subs, int x, int y)
{
int xroot = find(subs, x);
int yroot = find(subs, y); if (subs[xroot].rank < subs[yroot].rank)
{
subs[xroot].parent = yroot;
}
else if (subs[xroot].rank > subs[yroot].rank)
{
subs[yroot].parent = xroot;
}
else
{
//only need to increment its rank when ther are equal rank
subs[yroot].parent = xroot;
subs[xroot].rank++;
}
} bool isCycle(Graph *gra)
{
subSet *subs = new subSet[gra->V];
for (int i = 0; i < gra->V; i++)
{
subs[i].parent = i;//parent不能初始化为-1
subs[i].rank = 0;
} for (int e = 0; e < gra->E; e++)
{
int x = find(subs, gra->edges[e].src);
int y = find(subs, gra->edges[e].des); if (x == y) return true; unionTwo(subs, x, y);
} return false;
}
public:
UnionFindUnionByRank()
{
int V = 3, E = 3;
struct Graph* graph = new Graph(V, E); // add edge 0-1
graph->edges[0].src = 0;
graph->edges[0].des = 1; // add edge 1-2
graph->edges[1].src = 1;
graph->edges[1].des = 2; // add edge 0-2
graph->edges[2].src = 0;
graph->edges[2].des = 2; if (isCycle(graph))
printf( "Union By Rank found graph contains cycle \n" );
else
printf( "Union By Rank found graph doesn't contain cycle \n" );
}
};
Geeks Union-Find Algorithm Union By Rank and Path Compression 图环算法的更多相关文章
- 转 SQL Union和SQL Union All两者用法区别效率以及与order by 和 group by配合问题
SQL Union和SQL Union All两者用法区别效率以及与order by 和 group by配合问题 SQL Union和SQL Union All用法 SQL UNION 操作符 UN ...
- 关于UNION ALL与 UNION 用法和区别
(转自:http://www.cnblogs.com/EricaMIN1987_IT/archive/2011/01/20/1940188.html) UNION指令的目的是将两个SQL语句的结果合并 ...
- SQL Union和SQL Union All用法
SQL UNION 操作符 UNION 操作符用于合并两个或多个 SELECT 语句的结果集. 请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列.列也必须拥有相似的数据类型.同时,每 ...
- union 和 all union
sql union用法和sql union all用法,sql union效率 1.sql union用法 sql union在查询中可以将两个SQL 语句的结果合并起来.如果这样看的话, UNION ...
- 从Random Walk谈到Bacterial foraging optimization algorithm(BFOA),再谈到Ramdom Walk Graph Segmentation图分割算法
1. 从细菌的趋化性谈起 0x1:物质化学浓度梯度 类似于概率分布中概率密度的概念.在溶液中存在不同的浓度区域. 如放一颗糖在水盆里,糖慢慢溶于水,糖附近的水含糖量比远离糖的水含糖量要高,也就是糖附近 ...
- UNion ALL 和 UNION 的区别
UNION: 指定合并多个结果集并将其作为单个结果集返回.ALL: 将全部行并入结果中.其中包括重复行.如果未指定该参数,则删除重复行.
- linq 多个left join 和 sql union all -> linq union 方法
( from s in Base_SysMenus join r in Base_RoleRights on s.Menu_Id equals r.Menu_Id into temp f ...
- UNION ALL vs UNION
一直没意识到它们之间的区别,只知道UNION ALL在性能上优于UNION,忽略一个很重要的区别:UNION会去掉重复的行,而UNION ALL是包括所有行.
- [Union]C++中Union学习笔记
C++ union结构式一种特殊的类.它能够包含访问权限.成员变量.成员函数(可以包含构造函数和析构函数).它不能包含虚函数和静态数据变量.它也不能被用作其他类的基类,它本身也不能有从某个基类派生而来 ...
随机推荐
- AutoMapper: Mapper.Initialize() 只能调用一次,Why?
最开始的代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using S ...
- 《Windows核心编程》第五章——作业
#include <windows.h> #include<iostream> #include <tchar.h> using namespace std; ty ...
- 解决sqoop报错:java.lang.OutOfMemoryError: Java heap space
报错栈: -- ::, INFO [main] org.apache.sqoop.mapreduce.db.DBRecordReader: Executing query: = ) AND ( = ) ...
- 文件操作篇 close creat dup dup2 fcntl flock fsync lseek mkstemp open read sync write
文件操作篇 close creat dup dup2 fcntl flock fsync lseek mkstemp open read sync write close(关闭文件) 相关函数 ope ...
- 泛泰A870(高通600 cpu 720p) 刷4.4专用中文recovery TWRP2.7.1.1版(三版通刷)
欢迎关注泛泰非盈利专业第三方开发团队 VegaDevTeam (本team 由 syhost suky zhaochengw(z大) xuefy(大星星) tenfar(R大师) loogeo cr ...
- python部分重点底层源码剖析
Python源码剖析—Set容器(hashtable实现) python源码剖析(内存管理和垃圾回收)
- css美化、优化、合并工具推荐
其实很多时候,我们写完css规则之后,我们思考的无非就是3件事情: 验证 美化 压缩 当然无论是我们自己做这样的工具还是寻找一些比较好的成熟的工具,都有几个期望: 是否支持一些ie下的hack方式: ...
- jQuery实现新浪微博自动底部加载的方法
jQuery ScrollPagination plugin 是一个jQuery 实现的支持无限滚动加载数据的插件. 地址:http://andersonferminiano.com/jquerysc ...
- textarea自动增长宽高
<script type="text/javascript"> $(function(){ $("#iptcont").bind("key ...
- PHPnow For ASP&&ASP.NET&&MongoDB&&MySQL支持VC6.0编译器&&MySQL升级
可能和大家熟悉的是LAMP,Linux+Apache+Mysql+PHP,在Windows上,可能大家比较熟悉的是WAMP,Windows+Apache+Mysql+PHP,这是一个集成环境,说到集成 ...