數據結構之二叉樹

樹表明的是層級關係,一對多的關係。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?
        
    }
    
相關文章
相關標籤/搜索