树代表的是层级关系,一对多的关系。
二叉树是稳定的结构,并且孩子兄弟法是一种用二叉树的结构来描述任何形状树的方法。所以二叉树是最常使用的树结构。
树最常用的情况就是,
1.表示现实中的层级关系,
2.采用树这种天然分叉的存储结构来降低搜索成本,如左大右小,把线性结构搜索的n周期。立马减少到log2。
3.0和1编码以及二叉树来完成前缀编码。 并在前缀编码的基础上,发现了最小树的一种简便建立方法,hefuman树来进行非等概离数据的压缩。
总结:
树的遍历,是递归的概念。一个树由顶点,左树,右树构成。 而左树和右树也是同样是树,一层层递减,当树成为了一个叶子时候,而没有左右节点的时候就成了基本问题
树还是有复习的价值。可以复习下递归。 find 这个方法中说明一个问题递归要先认真做好分治,使得原问题等于小问题的组合,
并且体现递归思路的,最好别合并。没有十分清楚这句话是什么意思的话,一定要去看一下find方法第三行。
package com.linson.datastrcture; //// public class MyBinaryTree<T> { public static class MyBinaryNode<T> { public MyBinaryNode(T _element,MyBinaryNode<T> _leftNode,MyBinaryNode<T> _rightNode) { element=_element; leftNode=_leftNode; rightNode=_rightNode; } public T element; public MyBinaryNode<T> leftNode; public MyBinaryNode<T> rightNode; } public MyBinaryTree() { rootNode=null; } public MyBinaryTree(T _element) { rootNode=new MyBinaryNode<T>(_element, null, null); } //add public MyBinaryNode<T> insert(MyBinaryNode<T> fatherNode,boolean isLeft,T _value) { MyBinaryNode<T> result=null; if(fatherNode!=null) { MyBinaryNode<T> expectNode=isLeft==true?fatherNode.leftNode:fatherNode.rightNode; if(expectNode==null) { MyBinaryNode<T> tempNode=new MyBinaryNode<T>(_value, null, null); if(isLeft) { fatherNode.leftNode=tempNode; } else { fatherNode.rightNode=tempNode; } result=tempNode; } } return result; } //delete public void clear() { rootNode=null; } //find public MyBinaryNode<T> find(T _value) { return find(rootNode, _value); } //问题组合:找顶点,找左树,找右树。 最小规模:找顶点。如果是体现思路的代码就不要合并了。比如这里体现递归思路的,最好别合并。 private MyBinaryNode<T> find(MyBinaryNode<T> node,T _value) { MyBinaryNode<T> result=null; if(node!=null) { if(node.leftNode==null && node.rightNode==null)//最小规模,基本问题 { if(node.element.equals(_value)) { result=node; } } else//小一规模递归来组合。 { if(node.element.equals(_value)) { result=node; } else { result=find(node.leftNode, _value); if(result==null) { result=find(node.rightNode, _value); } } } //写的什么鬼,结果导向来写的代码,虽然运行正确,但是思路根本没清晰。 // if(node.element.equals(_value)) // { // resultBinaryNode=node; // } // else // { // resultBinaryNode=find(node.leftNode, _value); // if(resultBinaryNode==null) // { // resultBinaryNode=find(node.rightNode, _value); // } // } } return result; } //type:0:first print parent node .1 left children ,parent, right children. 2:left children ,right children parent. public void printTree(int type) { printTree(rootNode, type); } //打印树:组合:打印左树,打印节点,打印右树。基本情况:叶子。 private void printTree(MyBinaryNode<T> node,int type) { if(node==null) { System.out.println(""); return; } if(type==0) { //虽然省去这个判断,把下面这句和else下同样一句合并起来更简洁,但没有把递归的思路表达清晰,不利于人阅读。 if(node.leftNode==null && node.rightNode==null)//问题规模足够小,成了基本操作 { System.out.println(node.element.toString()); } else//非基本操作,需要递归来组合成原问题 { System.out.println(node.element.toString()); if(node.leftNode!=null) { printTree(node.leftNode, type); } if(node.rightNode!=null) { printTree(node.rightNode, type); } } } else if(type==1) { if(node.leftNode==null && node.rightNode==null) { System.out.println(node.element.toString()); } else { if(node.leftNode!=null) { printTree(node.leftNode, type); } System.out.println(node.element.toString()); if(node.rightNode!=null) { printTree(node.rightNode, type); } } } else { if(node.leftNode==null && node.rightNode==null) { System.out.println(node.element.toString()); } else { if(node.leftNode!=null) { printTree(node.leftNode, type); } if(node.rightNode!=null) { printTree(node.rightNode, type); } System.out.println(node.element.toString()); } } } public MyBinaryNode<T> rootNode=null; }
通用树的兄弟孩子结构,也是一种二叉树
package com.datastructurn; //应该是树应用最广的结构。 // public class ChildBrother<T> { //节点类不需要访问外部类的方法,设置为一个static也未尝不可。不一定是个内部类。可以是个嵌套类。 public static class ChildBrotherNode<T> { public T nodeValue; public ChildBrotherNode<T> child; public ChildBrotherNode<T> brother; public ChildBrotherNode<T> father;//冗余字段,空间换时间,用于简便删除操作,查找真上级,和真层级。 public ChildBrotherNode(T value,ChildBrotherNode<T> _child,ChildBrotherNode<T> _brother,ChildBrotherNode<T> _father) { nodeValue=value; child=_child; brother=_brother; father=_father; } public String toString() { String c=child==null?"":child.nodeValue.toString()+""; String b=brother==null?"":brother.nodeValue.toString()+""; String f=father==null?"":father.nodeValue.toString()+""; return nodeValue.toString();//+".father:"+f+".";//+" child:"+c+". "+". brother:"+brother+".father:"+f+"."; } } public ChildBrotherNode<T> root=null; public ChildBrother(T item) { root=new ChildBrotherNode<T>(item, null, null,null); } //add public ChildBrotherNode<T> Add(ChildBrotherNode<T> Node,boolean isChild,T value) { ChildBrotherNode<T> ret=null; if((isChild && Node.child==null)) { ret=new ChildBrotherNode<T>(value, null, null, Node);//node:father node. Node.child=ret; } else if((!isChild && Node.brother==null)) { ret=new ChildBrotherNode<T>(value, null, null, Node); Node.brother=ret; } return ret; } //remove public boolean remove(T value) { //find. check it is a leaf. boolean result=false; ChildBrotherNode<T> ret=find(value, root); if(ret!=null && ret.brother==null && ret.child==null) { boolean isborther=ret.father.brother.equals(ret); if(isborther) { ret.father.brother=null; } else { ret.father.child=null; } ret=null; result=true; } return result; } //modify,find & modify //find public ChildBrotherNode<T> find(T _value,ChildBrotherNode<T> rootNode) { ChildBrotherNode<T> ret=null; if(rootNode.nodeValue.equals(_value)) { ret=rootNode; } else { if(rootNode.brother!=null) { ret=find(_value, rootNode.brother); } if(ret==null && rootNode.child!=null) { ret=find(_value, rootNode.child); } } return ret; } public ChildBrotherNode<T> getRealFather(ChildBrotherNode<T> rootNode) { ChildBrotherNode<T> ret=null; if(rootNode!=null) { ChildBrotherNode<T> tempCheckNode=rootNode; while(tempCheckNode!=null) { if(tempCheckNode.father!=null) { if(tempCheckNode.father.child.equals(tempCheckNode)) { ret=tempCheckNode.father; break; } } tempCheckNode=tempCheckNode.father; } } return ret; } public int getRealLevel (ChildBrotherNode<T> Node) { int ret=0; ChildBrotherNode<T> RealFather= Node;// getRealFather(Node); while (RealFather!=null) { RealFather=getRealFather(RealFather); ret++; } return ret; } //type:0:first print parent node .1 left children ,parent, right children. 2:left children ,right children parent. public void printTree(int type) { printNodes(root, type,""); } private void printNodes(ChildBrotherNode<T> node,int type,String temp) { if(type==0) { System.out.println(temp+node.toString()); if(node.child!=null) { printNodes(node.child, type,temp+" "); } if(node.brother!=null) { printNodes(node.brother, type,temp+" "); } } else if(type==1) { if(node.child!=null) { printNodes(node.child, type,temp+" "); } System.out.println(temp+node.toString()); if(node.brother!=null) { printNodes(node.brother, type,temp+" "); } } else { if(node.child!=null) { printNodes(node.child, type,temp+" "); } if(node.brother!=null) { printNodes(node.brother, type,temp+" "); } System.out.println(temp+node.toString()); } } //update 2 node? myfater and my little brother? }