并查集的森林封装

采用了启发式策略,按秩合并和路径压缩技术。

/// @file        disjoint_set_forest.h
/// @brief       并查集
/// @copyright   玉涵,updated,2013/11/11

#include <iostream>
#include <vector>

using namespace std;

namespace algo
{
	/// @brief	并查集的森林表示法
	///			“压缩路径”+“按秩合并”优化时间
	///			线性时间复杂度,理论上是超线性的
	class DisjointSetForest
	{
	public:
		//集合中的一个元素
		struct DisjointSetNode
		{
			int Item;	//元素的值
			int Rank;	//元素的秩
			DisjointSetNode	*Parent;	//元素的父结点

			//构造函数,创建一个结点,对应MAKE-SET操作
			DisjointSetNode(int const &item):Item(item),Rank(0)
			{
				Parent = this;
			}
		};

		//创建一个集合 MAKE-SET
		static DisjointSetNode* MakeSet(int const &item)
		{
			return new DisjointSetNode(item);
		}

		//查找所属集合的操作:FIND-SET 使用了路径压缩
		static DisjointSetNode* FindSet(DisjointSetNode *a_set)
		{
			//路径压缩
			if(a_set != a_set->Parent)	//判断本身不是代表元素
			{
				a_set->Parent = FindSet(a_set->Parent);
			}
			return a_set->Parent;
		}

		//合并操作 UNION
		static void Union(DisjointSetNode* x, DisjointSetNode* y)
		{
			_Link(FindSet(x), FindSet(y));
		}

    private:
        static void _Link(DisjointSetNode* x, DisjointSetNode* y)
        {
            if(x->Rank > y->Rank)
            {
                y->Parent = x;
            }
            else
            {
                x->Parent = y;
            }

            //按秩合并
            if(x->Rank == y->Rank)
            {
                //秩相同时将默认作为根结点的y秩+1
                (y->Rank)++;
            }
        }
	};
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值