相同是查找一个图是否有环的算法,可是这个算法非常牛逼,构造树的时候能够达到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 图环算法的更多相关文章

  1. 转 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 ...

  2. 关于UNION ALL与 UNION 用法和区别

    (转自:http://www.cnblogs.com/EricaMIN1987_IT/archive/2011/01/20/1940188.html) UNION指令的目的是将两个SQL语句的结果合并 ...

  3. SQL Union和SQL Union All用法

    SQL UNION 操作符 UNION 操作符用于合并两个或多个 SELECT 语句的结果集. 请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列.列也必须拥有相似的数据类型.同时,每 ...

  4. union 和 all union

    sql union用法和sql union all用法,sql union效率 1.sql union用法 sql union在查询中可以将两个SQL 语句的结果合并起来.如果这样看的话, UNION ...

  5. 从Random Walk谈到Bacterial foraging optimization algorithm(BFOA),再谈到Ramdom Walk Graph Segmentation图分割算法

    1. 从细菌的趋化性谈起 0x1:物质化学浓度梯度 类似于概率分布中概率密度的概念.在溶液中存在不同的浓度区域. 如放一颗糖在水盆里,糖慢慢溶于水,糖附近的水含糖量比远离糖的水含糖量要高,也就是糖附近 ...

  6. UNion ALL 和 UNION 的区别

    UNION: 指定合并多个结果集并将其作为单个结果集返回.ALL: 将全部行并入结果中.其中包括重复行.如果未指定该参数,则删除重复行.

  7. 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 ...

  8. UNION ALL vs UNION

    一直没意识到它们之间的区别,只知道UNION ALL在性能上优于UNION,忽略一个很重要的区别:UNION会去掉重复的行,而UNION ALL是包括所有行.

  9. [Union]C++中Union学习笔记

    C++ union结构式一种特殊的类.它能够包含访问权限.成员变量.成员函数(可以包含构造函数和析构函数).它不能包含虚函数和静态数据变量.它也不能被用作其他类的基类,它本身也不能有从某个基类派生而来 ...

随机推荐

  1. 5. python 文本解析

    5. python 文本解析 这一章节我们简单的聊聊文本解析的两种方法: 1.分片,通过分片,记录偏移处,然后提取想要的字符串 例子: >>> line='aaa bbb ccc'  ...

  2. 如何利用javascript获取表单中select下拉列表中所选中项的值value

    1.html代码如下: <html> <head> </head> <body> <form name="form1" id= ...

  3. 2008技术内幕:T-SQL语言基础 联接查询摘记

    续 2008技术内幕:T-SQL语言基础 单表查询摘记 第三章 联接查询 Microsoft SQL Server 2008 支持四种表运算符 join(ANSI标准).apply(T-SQL扩展). ...

  4. AES算法工具类

    什么是对称加密算法? AES已经变成目前对称加密中最流行算法之一:AES可以使用128.192.和256位密钥,并且用128位分组加密和解密数据. 对称加密算法安全吗? 看过间谍局的知友们一定知道电台 ...

  5. 机器学习实战:用nodejs实现人脸识别

    机器学习实战:用nodejs实现人脸识别   在本文中,我将向你展示如何使用face-recognition.js执行可靠的人脸检测和识别 . 我曾经试图找一个能够精确识别人脸的Node.js库,但是 ...

  6. 硬件负载均衡F5和软负责均衡Nginx

    请直接搜索相关文章了解:http://www.ideadata.com.cn/wisdomAction/readWisdom.do?id=75   F5,硬件 优点:能够直接通过智能交换机实现,处理能 ...

  7. sqlalchemy简单示例

    1.初始化数据库database.py #!/usr/bin/env python # -*- coding: utf-8 -*- # Created by miaoshuijian on 2017/ ...

  8. 数学图形之Breather surface

    这是一种挺漂亮的曲面图形,可惜没有找到太多的相关解释. In differential equations, a breather surface is a mathematical surface ...

  9. java使用省略号代替多参数(参数类型... 参数名)

    J2SE 1.5提供了“Varargs”机制.借助这一机制,可以定义能和多个实参相匹配的形参.从而,可以用一种更简单的方式,来传递个数可变的实参.本文介绍这一机制的使用方法,以及这一机制与数组.泛型. ...

  10. iOS开发-UITableView常用方法

    UITableView常用来展示数据,类似于Android中的ListView,相对于Android中的ListView而言,UITableView的实现是非常简单,继承UITableViewData ...