前言:
今天开始学习算法,首先学习最基础的入门级算法——Quick-Find, 它主要是一个用来找连通关系的一个算法。比如说这里有五个人,A认识B, B认识C, C认识D, D认识E, 这样的话A就认识了E。A,B,C,D,E组成了一个关系链, 那么想想中国13亿人中有多少关系链呢?Who knows?还是先看看算法究竟是怎样的吧。
Quick-Find算法
我们先不谈13亿人的关系链,先来看看最简单的,拿8个数来举例:0,1,2,3,4,5,6,7,因为数字比较简单,我们就用一个整型数组ID来定义它,对ID进行初始化。
ID_array:
0 |
1 | 2 | 3 | 4 | 5 | 6 | 7 |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
ID[x]代表这个数的ID。
接下来进行union操作,就是把有联系的数连起来,其实很简单,就是把它们的ID改成一样的就行。
结果分析,之后来看看代码,这里用的是C++:
class quick_find{
private:
int cnt;//The count of connected component
public:
//p_ID is a pointer to ID_array
//find the root of p_ID[i]
int find(int *p_ID, int i)
{
return p_ID[i];
}
//initialize the ID of p_ID
void init_id(int *p_ID, int n)
{
cnt = n;
int i;
for(i = 0; i < n; i++){
p_ID[i] = i;
}
}
//the function of union
void union_num(int *p_ID, int length, int x, int y)
{
int i, ID_x, ID_y;
ID_x = find(p_ID, x);
ID_y = find(p_ID, y);
if(connected(p_ID, x, y) == false){
for(i = 0; i < length; i++){
if(p_ID[i] == ID_x){
p_ID[i] = ID_y;
}
}
cnt = cnt - 1;
}
}
//the function of connected
bool connected(int *p_ID, int x, int y){
if(find(p_ID, x) == find(p_ID, y)){
return true;
}
else{
return false;
}
}
//cout the cnt
void display(int *p_ID){
cout << cnt << endl;
}
};
来运行一下,就连接2-3,1-0,0-4,5-7,
#include <iostream>
using namespace std;
int main()
{
int i, n;
quick_find f;
int *p_ID;//p is the pointer to ID_array
cout << "Please enter the count of numbers: ";
cin >> n;
p_ID = new int[n];
f.init_id(p_ID, n);
for(i = 0; i < n; i++){
cout << p_ID[i] << " ";
}
cout << endl;
f.union_num(p_ID, n, 2, 3);
f.union_num(p_ID, n, 1, 0);
f.union_num(p_ID, n, 0, 4);
f.union_num(p_ID, n, 5, 7);
for(i = 0; i < n; i++){
cout << p_ID[i] << " ";
}
cout << endl;
f.display(p_ID);//display the count of connected components
return 0;
}
结果输出:
Please enter the count of numbers: 8
0 1 2 3 4 5 6 7
4 4 3 3 4 7 6 7
4
这里find函数非常简单,只是找出ID即可,时间复杂度为O(1),而Union函数因为无法确定谁的ID与之相同,所以每次都要把整个数组遍历一遍,如果一共有N个数,则时间复杂度为O(N)。
综合一下,如果是共有N个数,要连接其中M个,则最后时间复杂度为O(M*N)。
总结:
这个算法Find很快,而Union较慢,所以称为Quick-Find,当然之后还会有升级版,也就是Quick-Union和最终豪华版Union-Find,都会在之后的博客中继续学习。
最后强烈推荐Coursera上普林斯顿大学的算法课点击打开链接
以上内容纯属个人学习总结,不代表任何团体或单位。若有理解不到之处请见谅!