树与等价问题的Java实现
来源:互联网 发布:数据挖掘会议 2017 编辑:程序博客网 时间:2024/05/12 05:02
核心: 1: 根据给定等价关系划分等价类.
2: 用树来实现集合和集合操作.
3:为了便于实现集合操作, 树采用 "双亲表示法存储";
确定等价类的算法:(这里可以搜索详细的算法描述)
1:构造单个元素集合;
2:重复读入偶对,判定所属集合,进行合并;
划分等价类的三个集合操作:
1: 构造只含单个成员的集合.
2:判定某个单元素所在集合.
3:归并两个互不相交的集合为一个集合.
//树的表示. 一个集合就是一棵树;
1
2
3
4
5
6
7
8
//树的表示: 双亲表示法
class
ParentTree{
Object data;
//数据
ParentTree parent;
//该节点的父亲
}
以此为例来进行说明和程序演示:
假设集合S= {x | 1<= x <=8 } R是 S上的一个等价关系:
R = {(1,2),(3,4),(5,6),(7,8),(1,3),(5,7),(1,5)};
如题: 如果函数div_equalClass() 调用 find_mfset() 和 merge_mfset() 确定等价类,结果生成的树如下:
Java代码实现如下:
import java.util.ArrayList; //树与等价问题; MFset表示集合,它由n个子集合构成.//以此为例来进行说明和程序演示: //假设集合S= {x | 1<= x <=8 } R是 S上的一个等价关系: //R = {(1,2),(3,4),(5,6),(7,8),(1,3),(5,7),(1,5)}; public class MFset { //n个子集合,一个集合就是一棵树 private int n; private ParentTree[] mfSet; public MFset(Object[] Xi){ this.n = Xi.length; mfSet = new ParentTree[n+1]; initial(Xi); } //初始化操作,构造一个由n个子集Si...Sn(每个子集只含单个成员Xi)构成的集合S。 private void initial(Object[] Xi){ for(int i=0;i<Xi.length;i++){ mfSet[i+1] = new ParentTree(Xi[i]);//构造一个只含单个成员Xi的集合 } } //查找函数,确定x所属集合Si public ParentTree find_mfset(Object x){ ParentTree si = null; //找到存储x的节点 for(ParentTree ele : mfSet){ if(ele!=null && ele.toString().equals(x.toString())){ si = ele; break; } } if(si == null) return si;//x不存在 while(si.parent != null){ si = si.parent; } return si; } //查找函数 增强版,确定x所属集合Si,压缩路径:并将从i至根路径上的所有节点都变成根的孩子节点 public ParentTree fix_mfset(Object x){ ParentTree si = null; //找到存储x的节点 for(ParentTree ele : mfSet){ if(ele!=null && ele.toString().equals(x.toString())){ si = ele; break; } } if(si == null) return si;//x不存在 ArrayList<ParentTree> path = new ArrayList<>();//存储搜索路径 while(si.parent != null){ path.add(si); si = si.parent; } for(ParentTree ele : path)//将从i至根路径上的所有节点都变成根的孩子节点 ele.parent = si; return si; } //合并函数,将子集合Si和Sj中的一个并入另一个中,Si和Sj为子树根节点。 public void merge_mfset(ParentTree Si,ParentTree Sj){ if(Si == null || Sj==null)return; Sj.parent = Si; } //合并函数增强版, 并之前判断子集中所含成员的数目,然后令成员少的子树并入到含成员多的子树 // 因此需要修改存储结构,令根节点的parent域存储子集中所含成员数目的负值。初始为-1 // 另一种方法: 增加一个存储数目的域count // public void mix_mfset(ParentTree Si,ParentTree Sj){ //Si和Sj为子树根节点。 if(Si == null || Sj==null)return; if(Si.count > Sj.count){ Si.count += Sj.count; Sj.parent = Si; } else{ Sj.count += Si.count; Si.parent = Sj; } } //根据等价关系划分等价类,即 2:重复读入偶对,判定所属集合,进行合并; public void div_equalClass(NumPair[] numPairs){ for(int i=0;i<numPairs.length;i++){ ParentTree S1 = fix_mfset(numPairs[i].x);//增强版查找函数 ParentTree S2 = fix_mfset(numPairs[i].y); /*ParentTree S1 = find_mfset(numPairs[i].x);//原版查找函数 ParentTree S2 = find_mfset(numPairs[i].y);*/ if(S1 != S2){ merge_mfset(S1,S2);//合并普通版 //mix_mfset(S1,S2);//合并增强版 } } } public static void main(String[] args){ //演示集合{1,2,3,4,5,6,7,8} Integer[] S = new Integer[8]; for(int i=0;i<8;i++) S[i] = new Integer(i+1); MFset example = new MFset(S);// //等价关系 R = {(1,2),(3,4),(5,6),(7,8),(1,3),(5,7),(1,5)}; //确定等价类 NumPair[] numPairs = new NumPair[]{new NumPair(1, 2),new NumPair(3, 4),new NumPair(5, 6),new NumPair(7,8) ,new NumPair(1,3),new NumPair(5, 7),new NumPair(1, 5),new NumPair(8,9)}; example.div_equalClass(numPairs);//确定等价类 }} //数对class NumPair{ Object x; Object y; public NumPair(Object x,Object y){ this.x = x; this.y = y; }} //树的表示: 双亲表示法class ParentTree{ Object data ; //数据 int count = -1;//该树的元素数目 ParentTree parent = null; //该节点的父亲 public ParentTree(){}; public ParentTree(Object data){ this.data = data; } public String toString(){ return ""+data; }}
0 0
- 树与等价问题的Java实现
- 树与等价问题
- Java 泛型的理解与等价实现
- Java 泛型的理解与等价实现
- Java 泛型的理解与等价实现
- Java 泛型的理解与等价实现
- Java 泛型的理解与等价实现
- Java 泛型的理解与等价实现
- Java 泛型的理解与等价实现
- Java 泛型的理解与等价实现
- Java 泛型的理解与等价实现
- Java 泛型的理解与等价实现
- Java 泛型的理解与等价实现
- 数据结构 树(树与等价问题)
- 树的等价问题,并查集
- Regen的等价实现
- 树与等价类
- Java_泛型的理解与等价实现
- 1、struts2的入门
- usb.txt(temp)
- solr全文检索技术学习(二)-schema.xml配置解析
- android黑名单挂断电话(endCall)反射方法获取
- 链接、表格、层及页面总体的设计及使用
- 树与等价问题的Java实现
- unity 点击事件 点击 按钮还是屏幕
- 纯函数
- POJ-2329 Nearest number - 2
- Guava base -- Strings
- 循环List集合
- linux下导入、导出mysql数据库命令
- <Js>String
- java-时间处理:Date,DateFomat,Calendar