您的位置:首页 > 理论基础 > 数据结构算法

双亲树-等价类

2014-12-01 18:06 155 查看
用双亲树的思想实现了一个等价类。完成了路径压缩。算法仍然采用严蔚敏的教材中等价类章节中的算法。

/*  Author : Moyiii
*  Mail:  lc09@vip.qq.com
*  树的双亲表示法&等价类实现
*  仅作学习之用,当然如果
*  你想拿去用,随你好啦。
*/

#include<iostream>

using namespace std;

#define MAX_NODES 100

class PTree
{
public:
PTree();
void print();
void input();
int findClass(int a);
private:
void mergeNodes(int a,int b);
void fixNode(int a);
int nodes[MAX_NODES];
int nodeNum;
};

PTree :: PTree()
{
nodeNum = 0;
}

//输入两个数字,然后将这两个数字所在的集合合并成一个集合
void PTree :: input()
{
cout << "Please enter the amount of the nodes:";
cin >> nodeNum;
for(int i = 0; i < nodeNum; ++i)
{
nodes[i] = -1;
}
cout << "Please enter two numbers that belong to the same class" << endl;
cout << "End with -1 -1" << endl;
int m,n;
while(cin >> m >> n && m != -1 && n != -1)
{
if(m > nodeNum || n > nodeNum)
{
cout << "Error data!" << endl;
continue;
}
//从根合并
int i = findClass(m);
int j = findClass(n);
mergeNodes(i,j);
}
}

//找到根
int PTree :: findClass(int a)
{
fixNode(a);
while(nodes[a-1] > 0)
{
a = nodes[a - 1];
}
return a;
}

//将从a到a的根部之间的节点都直接指向a的根用来压缩路径
void PTree :: fixNode(int a)
{
//找到a的根节点
int paren = a;
while(nodes[paren - 1] > 0)
{
paren = nodes[paren - 1];
}
int temp = a;
//将a到根之间的节点都指向paren
while(nodes[temp - 1] > 0)
{
int x = nodes[temp - 1];
nodes[temp - 1] = paren;
temp = x;
}
return;
}

//合并两个等价类的根部,把节点少的合并到节点多的地方
void PTree :: mergeNodes(int a, int b)
{
//根节点的数据是负数,其绝对值代表这个等价类中有多少个数据
if(a == b)
{
return;
}

if(nodes[a - 1] < nodes[b - 1])
{
nodes[a - 1] += nodes[b - 1];
nodes[b - 1] = a;
fixNode(a);
}
else
{
nodes[b - 1] += nodes[a - 1];
nodes[a - 1] = b;
fixNode(b);
}
}

//打印函数
void PTree :: print()
{
cout << "----------Datas-----------" << endl;
for(int i = 0; i < nodeNum; ++i)
{
cout << i+1 << " " << nodes[i] << endl;
}
return;
}

/*测试数据
8
3 5
6 7
3 7
-1 -1
*/

int main()
{
PTree eq;
eq.input();
cout << eq.findClass(3) << endl;
eq.print();
return 0;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  等价类 数据结构