I come, I see, I conquer

                    —Gaius Julius Caesar

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

 

问题:下图中,怎样知道一个对象和另一个对象之间是否可达?

 

 

【union-find.h】

#ifndef __UNION_FIND__
#define __UNION_FINE__

#define TURE         1
#define FALSE        0
#define OK           1
#define ERROR        0

/* 节点个数 */
#define N            15

typedef 
int Status;
typedef unsigned 
char boolean;

/* QuickFind */
class QuickFind
{
public:
    
void quick_find();
    boolean find(
int p, int q);
    
void unite(int p, int q);
public:
    
int *id;
};

/* QuickUnion */
class QuickUnion
{
public:
    
void quick_union();
    
int root(int i);
    boolean find(
int p, int q);
    
void unite(int p, int q);
public:
    
int *id;
};

/* WeightedQU */
class WeightedQU
{
public:
    WeightedQU();
    
void weighted_qu();
    
int root(int i);
    boolean find(
int p, int q);
    
void unite(int p, int q);
public:
    
int *id;
    
int sz[N];
};

/* WeightedQUPathCompress */
class WQUPC
{
public:
    WQUPC();
    
void wqu_pc();
    
int root(int i);
    boolean find(
int p, int q);
    
void unite(int p, int q);
public:
    
int *id;
    
int sz[N];
};

#endif

 

 

 

【union-find.cpp】

 

/*******************************************************************************
/* <PRE>
/* 版权所有    : -
/* 模块名      : 并查集
/* 文件名      : union-find.cpp
/* 功能描述    : 并查集 
/* 作者        : <xxx>
/* 版本        : 1.0
/* -----------------------------------------------------------------------------
/* 备注        : -
/* -----------------------------------------------------------------------------
/* 修改记录    :
/* 日 期        版本     修改人        修改内容
/* 2011/01/01   1.0      <xxx>         创建
/* </PRE>
******************************************************************************
*/
#include 
<stdio.h>
#include 
<stdlib.h>
#include 
"union-find.h"

/* 打印set */
void printset(int id[]) 
{
    
for (int i = 0; i < N; i++
    {
        printf(
"%d ", id[i]);
    }
    printf(
"\n");
}


/******************************************************************************
/* 
/* QuickFind
/* 
/* 数据结构:
/* (1) 大小为N的整型数组id[]
/* (2) p和q如果id相同则认为它们是连通的
/*  
/*  i      0  1  2  3  4  5  6  7  8  9
/*  id[i]  0  1  2  9  9  6  6  7  8  9  //5和6是连通的; 2, 3, 4和9是连通的
/*  
/*  查找操作: 判断p和q的id值是否相同
/*  合并操作: 将包含p的块和包含q的块合并成一个新的块, 所有id值等于id[p]的对象
/*            将其id值设置成id[q]
/*
/*****************************************************************************
*/
void QuickFind::quick_find() 
{
    id 
= new int[N];
    
for (int i = 0; i < N; i++)  id[i] = i;
}

boolean QuickFind::find(
int p, int q) 
{
    
return id[p] == id[q];
}


void QuickFind::unite(int p, int q) {
    
int pid = id[p];
    
for (int i = 0; i < N; i++) {
        
if (id[i] == pid)
            id[i] 
= id[q];
    }
}



/******************************************************************************
/* 
/* QuickUnion
/* 
/* 数据结构:
/* (1) 大小为N的整型数组id[]
/* (2) id[i]是i的父亲
/* (3) i的根是id[id[id[...id[i]...]]]
/*  
/*  i      0  1  2  3  4  5  6  7  8  9
/*  id[i]  0  1  9  4  9  6  6  7  8  9
/* 
/*----------------------------------------------------------------------------
/*    0   1   9   6   7   8
/*           / \  |
/*          2   4 5
/*              |
/*              3
/*  3的根是9; 5的根是6
/*----------------------------------------------------------------------------  
/*  查找操作: 判断p和q的id的根是否相同
/*  合并操作: 将q的根的id值设置成p的根的id值
/*
/*****************************************************************************
*/
void QuickUnion::quick_union() 
{
    id 
= new int[N];
    
for (int i = 0; i < N; i++)  id[i] = i;
}

int QuickUnion::root(int i)
{
    
while (i != id[i]) i = id[i];  //时间正比于i的深度
    return i;
}

boolean QuickUnion::find(
int p, int q) 
{
    
return root(p) == root(q);
}

void QuickUnion::unite(int p, int q) {
    
int i = root(p);
    
int j = root(q);
    id[i] 
= j;
}



/******************************************************************************
/* 
/* WeightedQU
/* 
/* 数据结构:
/* (1) 大小为N的整型数组id[]
/* (2) id[i]是i的父亲
/* (3) i的根是id[id[id[...id[i]...]]]
/*  
/*  i      0  1  2  3  4  5  6  7  8  9
/*  id[i]  0  1  9  4  9  6  6  7  8  9
/* 
/*----------------------------------------------------------------------------
/*    0   1   9   6   7   8
/*           / \  |
/*          2   4 5
/*              |
/*              3
/*  3的根是9; 5的根是6
/*----------------------------------------------------------------------------  
/*  查找操作: 判断p和q的id的根是否相同
/*  合并操作: 将成员较小的树并入较大的树
/*            更新sz[]数组
/*
/*****************************************************************************
*/
WeightedQU::WeightedQU()
{
    
for (int i = 0; i < N; i++)  sz[i] = 1;
}

void WeightedQU::weighted_qu() 
{
    id 
= new int[N];
    
for (int i = 0; i < N; i++)  id[i] = i;
}

int WeightedQU::root(int i)
{
    
while (i != id[i]) i = id[i];  //时间正比于i的深度
    return i;
}

boolean WeightedQU::find(
int p, int q) 
{
    
return root(p) == root(q);
}

void WeightedQU::unite(int p, int q) {
    
int i = root(p);
    
int j = root(q);
    
if (sz[i] <= sz[j]) {id[i] = j; sz[j] += sz[i];}
    
else if (sz[i] > sz[j]) {id[j] = i; sz[i] += sz[j];}
}



/******************************************************************************
/* 
/* WeightedQUPathCompress
/* 
/* 数据结构:
/* (1) 大小为N的整型数组id[]
/* (2) id[i]是i的父亲
/* (3) i的根是id[id[id[...id[i]...]]]
/*  
/*  i      0  1  2  3  4  5  6  7  8  9
/*  id[i]  0  1  9  4  9  6  6  7  8  9
/* 
/*----------------------------------------------------------------------------
/*    0   1   9   6   7   8
/*           / \  |
/*          2   4 5
/*              |
/*              3
/*  3的根是9; 5的根是6
/*----------------------------------------------------------------------------  
/*  查找操作: 判断p和q的id的根是否相同
/*  合并操作: 将成员较小的树并入较大的树
/*            更新sz[]数组
/*            计算出i的根后, 将每一个检查过的节点的id值设置成root(i)
/*
/*****************************************************************************
*/
WQUPC::WQUPC()
{
    
for (int i = 0; i < N; i++)  sz[i] = 1;
}

void WQUPC::wqu_pc() 
{
    id 
= new int[N];
    
for (int i = 0; i < N; i++)  id[i] = i;
}

int WQUPC::root(int i)
{
    
while (i != id[i]) 
    {
        id[i] 
= id[id[i]];
        i 
= id[i];
    }
    
return i;
}

boolean WQUPC::find(
int p, int q) 
{
    
return root(p) == root(q);
}

void WQUPC::unite(int p, int q) {
    
int i = root(p);
    
int j = root(q);
    
if (sz[i] <= sz[j]) {id[i] = j; sz[j] += sz[i];}
    
else if (sz[i] > sz[j]) {id[j] = i; sz[i] += sz[j];}
}



/*******************************************************************************
/* <FUNC>
/* 函数名   : main
/* 功能     : 测试函数
/* 参数     : -
/* 返回值   : -
/* 备注     : -
/* 作者     : <xxx>
/* </FUNC>
******************************************************************************
*/
void main()
{
    
/*quick find*/
    QuickFind qf;
    printf(
"\nquick_find: \n\n");
    qf.quick_find();  printf(
"%s""original:   ");   printset(qf.id);

    qf.unite(
10);  printf("unite(1,0): "); printset(qf.id);
    qf.unite(
20);  printf("unite(2,0): "); printset(qf.id);
    qf.unite(
03);  printf("unite(0,3): "); printset(qf.id);
    qf.unite(
45);  printf("unite(4,5): "); printset(qf.id);
    qf.unite(
56);  printf("unite(5,6): "); printset(qf.id);
    qf.unite(
78);  printf("unite(7,8): "); printset(qf.id);

    
if (qf.find(03)) printf("find: 0 and 3 %s""in the same set!\n");
    
if (qf.find(49)) printf("find: 4 and 9 %s""in the same set!\n");

    
/*quick union*/
    QuickUnion qu;
    printf(
"\n\nquick_union: \n\n");
    qu.quick_union();  printf(
"%s""original:   ");   printset(qu.id);
    
    qu.unite(
10);  printf("unite(1,0): "); printset(qu.id);
    qu.unite(
20);  printf("unite(2,0): "); printset(qu.id);
    qu.unite(
03);  printf("unite(0,3): "); printset(qu.id);
    qu.unite(
45);  printf("unite(4,5): "); printset(qu.id);
    qu.unite(
56);  printf("unite(5,6): "); printset(qu.id);
    qu.unite(
78);  printf("unite(7,8): "); printset(qu.id);
    
    
if (qu.find(03)) printf("find: 0 and 3 %s""in the same set!\n");
    
if (qu.find(49)) printf("find: 4 and 9 %s""in the same set!\n");

    
/*weighted quick union*/
    WeightedQU wqu;
    printf(
"\n\nweighted quick union: \n\n");
    wqu.weighted_qu();  printf(
"%s""original:   ");   printset(wqu.id);
    
    wqu.unite(
10);  printf("unite(1,0): "); printset(wqu.id);
    wqu.unite(
20);  printf("unite(2,0): "); printset(wqu.id);
    wqu.unite(
03);  printf("unite(0,3): "); printset(wqu.id);
    wqu.unite(
45);  printf("unite(4,5): "); printset(wqu.id);
    wqu.unite(
56);  printf("unite(5,6): "); printset(wqu.id);
    wqu.unite(
78);  printf("unite(7,8): "); printset(wqu.id);
    
    
if (wqu.find(03)) printf("find: 0 and 3 %s""in the same set!\n");
    
if (wqu.find(49)) printf("find: 4 and 9 %s""in the same set!\n");

    
/*weighted quick union with path compression*/
    WQUPC wqupc;
    printf(
"\n\nweighted quick union with path compression: \n\n");
    wqupc.wqu_pc();  printf(
"%s""original:   ");   printset(wqupc.id);
    
    wqupc.unite(
10);  printf("unite(1,0): "); printset(wqupc.id);
    wqupc.unite(
20);  printf("unite(2,0): "); printset(wqupc.id);
    wqupc.unite(
03);  printf("unite(0,3): "); printset(wqupc.id);
    wqupc.unite(
45);  printf("unite(4,5): "); printset(wqupc.id);
    wqupc.unite(
56);  printf("unite(5,6): "); printset(wqupc.id);
    wqupc.unite(
78);  printf("unite(7,8): "); printset(wqupc.id);
    
    
if (wqupc.find(03)) printf("find: 0 and 3 %s""in the same set!\n");
    
if (wqupc.find(49)) printf("find: 4 and 9 %s""in the same set!\n");
}

 

 

posted on 2011-04-29 23:25  jcsu  阅读(524)  评论(0编辑  收藏  举报