FreeTree
整个类代码粘贴即可使用
香♂蕉树 使用数组链表记录分支的树
树内分支对象不可重复
每个树对象都是分支 包含一个数据节点 同时也是子树
每个子书都可以访问整颗树 整个树都可以互相交换子树或者插入其它树的分支
里面有几个 方法 可以返回 整个树的所有子树的Stream 和所有data的Stream
试用主函数可大改了解该数据结构怎样使用
注意每个树都有deep(所在分支深度属性)getdeep是通过遍历根节点实时计算的 效率萎靡
package Kit.DataStrcture;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.function.Consumer;
import java.util.stream.Stream;
/**
* Created by duke29 on 2019/6/12.
* <p>
* The main tree is rootNode
* everyNode Mean a brunch Tree
*/
public class FreeTree<DATA> {
/
DATA data = null;
public DATA getData() {
return data;
}
//The root is the first Node in whole Tree
//Treefield
FreeTree<DATA> TreeRoot = this;
//share this map in whole Tree
private LinkedHashMap<FreeTree<DATA>, DATA> allNodeMap = null;
//Treefield
//Nodefield
private FreeTree<DATA> superNode = this;
private final ArrayList<FreeTree<DATA>> branchlist = new ArrayList<>();
/Nodefield
//____________________nodebehaviour//
public boolean inSameTree(FreeTree TreeNode_toCheck) {
return TreeRoot.equals(TreeNode_toCheck.TreeRoot);
}
public boolean isLeafNode() {
return branchlist.isEmpty();
}
public boolean isRootNode() {
return TreeRoot == this;
}
/**
* Supper Root Node In this Tree
*/
public FreeTree<DATA> getSuperNode() {
return superNode;
}
/**
* RootNode deep 0 is root ___ from0-n
*/
public int getDeep() {
int deep = 0;
FreeTree recorderLabel = this;
while (!recorderLabel.isRootNode() && deep < 1000000) {
recorderLabel = recorderLabel.getSuperNode();
deep++;
}
return deep;
}
static final ArrayList emptyList = new ArrayList(0);
public ArrayList<FreeTree<DATA>> getALLChildbrunch() {
if (isLeafNode()) {
return emptyList;
} else {
return branchlist;
}
}
public ArrayList<FreeTree<DATA>> getPartnersbrunch() {
if (isRootNode()) {
return emptyList;
} else {
return superNode.branchlist;
}
}
public FreeTree<DATA> independent() {
independentFromLocaTree();//todo
return this;
}
//____________________nodebehaviour//
//____________________Treebehaviour//
/*
* repeatNode will not add in
*/
@SafeVarargs
public final void addbrunchNode(FreeTree<DATA>... branchNodes) {
for (FreeTree<DATA> branchNode : branchNodes) {
if (allNodeMap != null) {
//addnode in a node
if (!allNodeMap.containsKey(branchNode)) {
System.out.println("add Node" + branchNode.data);
branchlist.add(branchNode);
branchNode.jointoOtherTree(this);
}
} else {
System.out.println("add Node in rooot " + branchNode.data);
allNodeMap = new LinkedHashMap<>();//init allNodeMap in rootNode
allNodeMap.put(this, data);//put rootNode into Map
branchlist.add(branchNode);//add the Node Into Tree
branchNode.jointoOtherTree(this);
}
}
}
/**
* remove a ndoe if tree contian it
* this node will dependent to a new tree
*/
public boolean removeAbrunch(FreeTree<DATA> leafNode) {
if (allNodeMap != null) {
if (allNodeMap.containsKey(leafNode)) {
leafNode.independentFromLocaTree();
return true;
} else {
return false;
}
} else {
return false;
}
}
/**
* Scene all brunch Node under this tree except this one
*/
public void scanebrunch(Consumer<FreeTree<DATA>> consumer) {
this.branchlist.forEach(freeTree -> {
consumer.accept(freeTree);
if (!freeTree.isLeafNode()) {
freeTree.scanebrunch(consumer);
}
});
}
public Stream<FreeTree<DATA>> wholeTreeStream() {
Stream<FreeTree<DATA>> wholeTreeStream;
if (allNodeMap != null) {
wholeTreeStream = allNodeMap.keySet().stream();
} else {
wholeTreeStream = new ArrayList<FreeTree<DATA>>().stream();
}
return wholeTreeStream;
}
public Stream<DATA> allDataStream() {
Stream<DATA> dataStream;
if (allNodeMap != null) {
dataStream = allNodeMap.values().stream();
} else {
dataStream = new ArrayList<DATA>().stream();
}
return dataStream;
}
public boolean containTree(FreeTree freeTree) {
return allNodeMap.containsKey(freeTree);
}
//____________________Treebehaviour/
private void independentFromLocaTree() {
if (!isRootNode()) {
if (allNodeMap != null) {
LinkedHashMap<FreeTree<DATA>, DATA> oldMAp = allNodeMap;
LinkedHashMap<FreeTree<DATA>, DATA> newMap = new LinkedHashMap<>();
newMap.put(this, this.data);
superNode.branchlist.remove(this);
oldMAp.remove(this);
this.changeAllNodeMap(newMap).setSupper(this).setRoot(this);
this.scanebrunch(freeTree -> {
oldMAp.remove(freeTree);
newMap.put(freeTree, (DATA) freeTree.data);
freeTree.changeAllNodeMap(newMap).setRoot(this);
});
}
}
}
private void jointoOtherTree(FreeTree<DATA> TreeNodetojoin) {
if (isRootNode()) {
// System.out.println("joint a root"+data);
if (allNodeMap == null) {
TreeNodetojoin.allNodeMap.put(this, data);
} else {
TreeNodetojoin.allNodeMap.putAll(allNodeMap);
}
this.changeAllNodeMap(TreeNodetojoin.allNodeMap).setSupper(TreeNodetojoin).setRoot(TreeNodetojoin);
} else {
if (allNodeMap != null) {
LinkedHashMap<FreeTree<DATA>, DATA> oldMAp = this.allNodeMap;
LinkedHashMap<FreeTree<DATA>, DATA> newMap = TreeNodetojoin.allNodeMap;
newMap.put(this, data);
this.changeAllNodeMap(newMap).setSupper(TreeNodetojoin).setRoot(TreeNodetojoin.TreeRoot);
superNode.branchlist.remove(this);
oldMAp.remove(this);
this.scanebrunch(freeTree -> {
oldMAp.remove(freeTree);
newMap.put(freeTree, freeTree.data);
freeTree.changeAllNodeMap(newMap).setRoot(TreeNodetojoin);
});
}
}
}
private FreeTree<DATA> setSupper(FreeTree<DATA> suppernode) {
this.superNode = suppernode;
return this;
}
private void setRoot(FreeTree<DATA> rootNode) {
this.TreeRoot = rootNode;
}
private FreeTree<DATA> changeAllNodeMap(LinkedHashMap<FreeTree<DATA>, DATA> allNodeMap) {
this.allNodeMap = allNodeMap;
return this;
}
//
//node type and node layer info
//init
public FreeTree(DATA data) {
this.data = data;
// this.sensor.addListener((obs#ervable, oldValue, newValue) -> System.out.println("node changeing "));
}
public static void main(String argsp[]) {
FreeTree<String> superroot = new FreeTree<>("jbroot");
FreeTree<String> root = new FreeTree<>("root");
FreeTree<String> node = new FreeTree<>("node");
FreeTree<String> xnode = new FreeTree<>("nodex");
FreeTree<String> node1 = new FreeTree<>("node1");
FreeTree<String> node2 = new FreeTree<>("node2");
FreeTree<String> node3 = new FreeTree<>("node3");
root.addbrunchNode(node, xnode);
node.addbrunchNode(node1, node2, node3);
root.wholeTreeStream().forEach(stringFreeTree -> {
System.out.println(stringFreeTree.getData());
System.out.println(stringFreeTree.getDeep());
});
node.allDataStream().forEach(s -> {
System.out.println(s);
});
System.out.println("musturbation");
//
// System.out.println(“removeAbrunch fack shit”);
root.removeAbrunch(node)
// root.allDataStream().forEach(s -> {
// System.out.println(s);
// });
// System.out.println("node!!!!!!");
// node.allDataStream().forEach(s -> {
// System.out.println(s);
// });
//
// node.wholeTreeStream().forEach(stringFreeTree -> {
// System.out.println(stringFreeTree.getDeep());
// System.out.println(stringFreeTree.getData());
// });
superroot.addbrunchNode(root);
root.allNodeMap.forEach((stringFreeTree, s1) -> {
System.out.println(s1);
});
superroot.allDataStream().forEach(
s -> {
System.out.println(s);
}
);
superroot.wholeTreeStream().forEach(
s -> {
System.out.println(s.getData());
}
);
// superroot.scanebrunch(stringFreeTree -> System.out.println(stringFreeTree.getData()));
//root.scanebrunch(stringFreeTree -> System.out.println(stringFreeTree.getData()));
// superroot.scanebrunch(stringFreeTree -> System.out.println(stringFreeTree.getData()));
}
}