dynamic-connectivity 动态连通性问题之 quick-find 算法

问题描述:java

如上图,给定一个数组,size = N ,若是 p 和 q 的 id 相等则 p 和 q 连通算法

对象连通的特性:数组

一、自反性:p 恒定连通 p 自身。测试

二、对称性:若是 p 连通 q ,则 q 连通 p 。ui

三、传递性:若是 p 连通 q ,q 连通 r ,则 p 连通 r 。code

这里简单运用对数组 id[] 的访问(读或写)次数去考虑采用 quick-find 算法的时间复杂度。对象

算法类源码:blog

public class QuickFindUF {
	private int[] id;
	
	public QuickFindUF(int size) {
		id = new int[size];
		for (int i = 0; i < size; i++) {
			id[i] = i;
		}
	}
	
	public boolean connected(int p, int q) {
		return id[p] == id[q];
	}
	
	public void union(int p, int q) {
		int pid = id[p];
		int qid = id[q];
		for (int i = 0; i < id.length; i++) {
			if (id[i] == pid) {
				id[i] = qid;
			}
		}
	}
	
	public String toString() { //这里为了方便观看数组的变化,我重写了 toString() 方法
		String temp = "[";
		for (int i = 0; i < id.length; i++) {
			if (i == id.length - 1) {
				temp += id[i] + "]";
				break;
			}
			temp += id[i] + ", ";
		}
		return temp;
	}
}

测试类源码(附带算法时间复杂度分析):源码

public class TestQuickFind {
	public static void main(String[] args) {
		QuickFindUF qf = new QuickFindUF(10); //访问(读或写)id[] 10次(N)
		qf.union(5, 0); //访问id[] 10 + 2 次
		System.out.println(qf); //结果:[0, 1, 2, 3, 4, 0, 6, 7, 8, 9]
		qf.union(6, 5); //访问id[] 10 + 2 次
		System.out.println(qf); //结果:[0, 1, 2, 3, 4, 0, 0, 7, 8, 9]
		//到此已链接了0, 5, 6三个整数(对象),总共访问id[](2 + 1) * (10 + 2)次(3N)
		//若链接0, 5, 6, 9四个整数(对象),以下:
		qf.union(9, 6); //访问id[] 10 + 2 次
		//总共是(3 + 1) * (10 + 2) 次(4N)
		//因此往下推导将N个对象链接起来,
		//至少须要访问(N - 1)*(N + 2)+ N = N * N + 2N - 2 = (N + 1)*(N + 1)- 3 次id[]
		System.out.println(qf.connected(6, 0));
		//connected访问id[] 2次
	}
}

须要注意的是:io

链接 N 个对象只须要 N - 1 次 union,访问数组(N - 1)*(N + 2)次 。new QuickFindUF(N) 是访问数组 N 次。因此二者相加,总共访问数组:(N - 1)*(N + 2)+ N = (N + 1)*(N + 1)- 3 次

能够看到,connected() 的时间复杂度是 O(1) ,当调用 n 次此方法,则时间复杂度为增为 O(n) ;union() 的时间复杂度为 O(n) ,若调用 n 次此方法,则复杂度变为 O(n * n) (2次方打不出来,很差意思哈)。

在 main 方法里的测试代码整体时间复杂度是 O(n * n) 级别的,即 quick-find 算法的查找对象并检查两个对象是否连通(connected())的速度是很快的(O(1) ~ O(n)),属于线性增加;可执行 union() 时,速度不尽如人意,时间复杂度属于幂增加,以目前计算机硬件的运算水准来看是较为消耗运算时间的一种算法。

相关文章
相关标签/搜索