樹表明的是層級關係,一對多的關係。node
二叉樹是穩定的結構,而且孩子兄弟法是一種用二叉樹的結構來描述任何形狀樹的方法。因此二叉樹是最常使用的樹結構。編碼
樹最經常使用的狀況就是,spa
1.表示現實中的層級關係,code
2.採用樹這種自然分叉的存儲結構來下降搜索成本,如左大右小,把線性結構搜索的n週期。立馬減小到log2。blog
3.0和1編碼以及二叉樹來完成前綴編碼。 並在前綴編碼的基礎上,發現了最小樹的一種簡便創建方法,hefuman樹來進行非等概離數據的壓縮。遞歸
總結:element
樹的遍歷,是遞歸的概念。一個樹由頂點,左樹,右樹構成。 而左樹和右樹也是一樣是樹,一層層遞減,當樹成爲了一個葉子時候,而沒有左右節點的時候就成了基本問題rem
樹仍是有複習的價值。能夠複習下遞歸。 find 這個方法中說明一個問題遞歸要先認真作好分治,使得原問題等於小問題的組合,get
而且體現遞歸思路的,最好別合併。沒有十分清楚這句話是什麼意思的話,必定要去看一下find方法第三行。it
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? }