Quick-Find算法

前言:

    今天开始学习算法,首先学习最基础的入门级算法——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上普林斯顿大学的算法课点击打开链接




以上内容纯属个人学习总结,不代表任何团体或单位。若有理解不到之处请见谅!









猜你喜欢

转载自blog.csdn.net/qq_39747794/article/details/80244560