树是一种非线性数据结构,将树的结构以图形展示出来有助于理解
- 主要步骤
- 一个树节点
- da’ta:节点所维护的一个对象
- children:盛装子节点的容器
- father:记录父节点
- NAXSIZE:最大子节点数量,NAXSIZE=2时即二叉树
- FIXED:节点转字符串时固定大小
- 字符缓存区
- 树到字符串缓存区的映射
- 节点与树的相对坐标:
W(宽度):该节点右边所有叶子节点的数量
H(高度):相对于根节点的高度
比如“5”的X为:4 ,为:3 - 节点到缓存区的映射关系:
X=W*FIXED+FIXED/2
Y=H*4-4
代码实现
public class Tree<D> {
private List<Tree<D>> children;
private D data;
private int NAXSIZE=10;
public Tree<D> father;
public static int FIXED =4;
public Tree(D data) {
this.data=data;
}
public void add(Tree<D> child) {
if(this.children==null) {
this.children=new ArrayList<Tree<D>>();
}
if(this.NAXSIZE>this.children.size()) {
this.children.add(child);
child.setFather(this);
}else
System.out.println("Tree children overflow");
}
public void setFather(Tree<D> father) {
this.father=father;
}
public int getUpwardX(Tree<D> root,int x) {
if(this==root) {
return x;
}
if(root.children!=null) {
for(Tree<D> child:root.children) {
if(!child.isChild(this)) {
x+=child.getWidth();
}else {
return getUpwardX(child,x);
}
}
}
return 0;
}
public int getDownX() {
if(this.children!=null&&this.children.size()>1) {
int x=0;
for(int i=0;i<this.children.size();i++) {
if(i==this.children.size()-1) {
x+=this.children.get(i).getWidth()*FIXED/2;
}
else
x+=this.children.get(i).getWidth();
}
return x;
}
return 0;
}
public int getUpwardY(Tree<D> root) {
if (this==root) {
return 1;
}else if(this.father==null) {
return 1;
} else
return 1+this.father.getUpwardY(root);
}
public int getHeight() {
if(this.children==null||this.children.size()==0)
return 1;
int maxHeight=0;
for(Tree<D> child:this.children) {
int childHeight = child.getHeight();
maxHeight=maxHeight>childHeight?maxHeight:childHeight;
}
return maxHeight+1;
}
public int getWidth() {
if(this.children==null||this.children.size()==0)
return 1;
int width=0;
for(Tree<D> child:this.children) {
width+=child.getWidth();
}
return width;
}
public void show() {
int height = this.getHeight();
int width = this.getWidth();
Buffer buffer=new Buffer(height*4,width*FIXED);
show(this,buffer,0,0);
System.out.println(buffer);
}
public void show(Tree<D> root, Buffer buffer ,int x,int y) {
int upwardX = this.getUpwardX(root,0);
int downX=this.getDownX();
int upwardY=this.getUpwardY(root);
int nodey = 4*upwardY-4;
int nodex = upwardX*FIXED+downX;
buffer.replace(nodex,nodey , this.toString());
if(this!=root){
link(buffer,nodex+FIXED/2-1,nodey,x,y);
}
if(this.children!=null) {
for(Tree<D> child:this.children) {
child.show(root,buffer,nodex+FIXED/2-1,nodey);
}
}
}
public void link(Buffer buffer,int cx,int cy,int fx ,int fy) {
buffer.replace(cx, cy-1, "|");
buffer.replace(cx, cy-2, "+");
if(cx<fx) {
for(int i=cx+1;i<fx;i++) {
buffer.replace(i, cy-2, "-");
}
}else {
for(int i=cx-1;i>fx;i--) {
buffer.replace(i, cy-2, "-");
}
}
buffer.replace(fx, fy+2, "+");
buffer.replace(fx, fy+1, "|");
}
public boolean isChild(Tree<D> node) {
if(this==node) {
return true;
}else if(this.children!=null) {
for(Tree<D> child:this.children) {
if(child.isChild(node)) {
return true ;
}
}
}
return false;
};
public static String repeatString(String str,int c) {
String tmp=str;
while(c>0)
tmp+=str;
return tmp;
}
public String toString() {
String str = this.data.toString();
if(str.length()>FIXED) {
str=str.substring(0, FIXED);
}
int x=FIXED-str.length()+1;
for(int i=0;i<x/2;i++) {
str+=" ";
}
return String.format("%"+FIXED+"s", str);
}
}
class Buffer{
int height;
int width;
StringBuilder[] list;
public Buffer(int height,int width) {
this.height=height;
this.width=width;
list=new StringBuilder[height];
String line="";
while(line.length()<width)
line+=" ";
for(int h=0;h<height;h++) {
StringBuilder tmp=new StringBuilder(line);
list[h]=tmp;
}
}
public void replace(int x, int y, String string) {
list[y].replace(x, x+string.length(), string);
}
public String toString() {
String tmp="";
for(StringBuilder line:list) {
tmp+=line+"\n";
}
return tmp;
}
}
测试
public static void main(String[] args) {
Tree<Integer> root=new Tree<Integer>(0);
Tree<Integer> node1=new Tree<Integer>(1);
Tree<Integer> node2=new Tree<Integer>(2);
Tree<Integer> node3=new Tree<Integer>(3);
Tree<Integer> node4=new Tree<Integer>(4);
Tree<Integer> node5=new Tree<Integer>(5);
Tree<Integer> node6=new Tree<Integer>(6);
Tree<Integer> node7=new Tree<Integer>(7);
root.add(node1);
root.add(node2);
node2.add(node3);
node2.add(node4);
node2.add(node5);
node5.add(node6);
node5.add(node7);
}
打印整棵树
root.show();
打印子树
node2.show();
添加节点
node1.add(new Tree<Integer>(11));
node1.add(new Tree<Integer>(12));
root.show();