Disjuntos-set
contorno
propiedad
- Una estructura de árbol
- algoritmo disjuntos-set no admite la división de un conjunto de
elemento
- representantes de yuanes
- Elementos de la colección, usan para representar el conjunto de
- Todos los elementos de un conjunto para representar organizan en una estructura de árbol es el elemento raíz
- padre [x]
- Para cada elemento, los padres [x] x padre punto de nodo en la estructura de árbol. Si x es un nodo raíz, por lo que el padre [x] = x
operativo
- MakeSet
- Inicialización disjuntos-set
- El establecimiento de un representante de
-
function MakeSet(x) // 参数 => 选定的代表元 x.parent := x
- Encontrar
- La determinación de qué subconjunto de elementos que pertenecen a devolver un conjunto de representante metadatos del elemento pertenece
- Método => puede continuar a moverse hacia arriba en la estructura de árbol a lo largo de un padre [x], hasta alcanzar el nodo raíz
- Determinar si los dos pertenecen al mismo conjunto de elementos, ya sea sólo tienen el mismo aspecto a sus representantes yuanes
-
function Find(x) // 参数 => 带查找的元素 if x.parent == x // 到达根节点 return x else return Find(x.parent)
- Unión
- En los dos subconjuntos y la misma colección
-
function Union(x, y) xRoot := Find(x) yRoot := Find(y) xRoot.parent := yRoot
optimización Uuion disjuntos-set
- Y ese conjunto el método más básico para comprobar si la representación de matriz
- Rendimiento inferior al método de la lista, ya que el árbol puede crear un grave desequilibrio, ciertas ramas de profundidad demasiado alto
- optimización del balance
- Por fusión rango
-
Siempre será un pequeño árbol conectado a un árbol grande
-
Rango: Profundidad
-
Afectar el tiempo de ejecución es la profundidad del árbol, añadir árboles más pequeños no aumentará en la misma fila tras fila a menos que tengan raíces más profundas del árbol
-
Definido como un único rango elemento 0, cuando se combina con dos RANK es árboles R, su rango r + 1
-
El peor caso el tiempo complejidad de O (logN)
-
function MakeSet(x) // 初始化 x.parent := x x.rank := 0 // 并查集树结构每个节点包含秩信息
-
function Union(x, y) // 合并 xRoot := Find(x) yRoot := Find(y) if xRoot == yRoot return // x和y不在同一个集合,合并他们。 if xRoot.rank < yRoot.rank xRoot.parent := yRoot else if xRoot.rank > yRoot.rank yRoot.parent := xRoot else yRoot.parent := xRoot xRoot.rank := xRoot.rank + 1
-
- compresión de caminos
- El método de realización de una estructura de árbol cuando la plana "búsqueda"
- Cada nodo en el camino se puede conectar directamente a la raíz
- Encuentra de forma recursiva a través del árbol, cada nodo de la referencia cambiada a la raíz del árbol para dar una más plana, después de la aceleración del nodo de operación directa o indirectamente referencias
-
function Find(x) if x.parent != x x.parent := Find(x.parent) // 将每个节点引用到根节点 return x.parent
- algoritmo óptimo Progresivo: Fredman y Saks explica el tiempo O promedio (N) en 1989 puede conseguir cualquier disjuntos-set
- Por fusión rango
- optimización del balance
La operación principal
- Las operaciones anteriores se supone elementos independientes que pertenecen, respectivamente, a un conjunto separado en
- Fusionar dos conjuntos disjuntos
- Configuración de una matriz matriz, x representa el número de padres
- Fusionar dos conjuntos disjuntos de qué manera es encontrar una recopilación de los antepasados, el ancestro de otro conjunto de un padre para él
-
void Union(int x, int y) { xRoot = Find(x); // 找到始祖 yRoot = Find(y); // 找到始祖 if (xRoot != yRoot) parent[xRoot] = yRoot; // x -> y }
- El análisis de dos elementos pertenecen al mismo conjunto
- Mirando antepasado, el antepasado de la comparación son los mismos
-
bool same(int x, int y) { return Find(x) == Find(y); // 比较始祖是否相同 }
Y un conjunto de optimización de búsqueda
- compresión de caminos
-
int getfather(int v) { if (parent[v] == v) // 根节点 return v; // 返回始祖 else { parent[v] = getfather(parent[v]); // 路径压缩【递归】 return parent[v]; // 返回并查集根节点 } }
-
- rango de fusión
- La profundidad mínima de la colección más profundo de elementos donde la colección se fusionará en el elemento en el cual
-
void judge(int x, int y) { // 寻找始祖 xRoot = Find(x); yRoot = Find(y); if (rank[xRoot] > rank[yRoot]) parent[yRoot] = xRoot; else { parent[xRoot] = yRoot; // 以yRoot为始祖 if (rank[xRoot] == rank[yRoot]) ++rank[yRoot]; // 重要的是始祖的rank,只修改始祖的,其他的不用管 } }
- inicialización
memset(rank, 0, sizeof(int)*rank_size);
El tiempo y el espacio complejidad
- complejidad del tiempo
- procedimiento de optimización de compresión Path simultáneamente, por rango (Escala) combinado tiempo medio de complejidad de cada operación es O (N)
- espacio complejidad
- O (N) N es el número de elementos