数据结构之二叉树

树代表的是层级关系,一对多的关系。

二叉树是稳定的结构,并且孩子兄弟法是一种用二叉树的结构来描述任何形状树的方法。所以二叉树是最常使用的树结构。

树最常用的情况就是,

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?
        
    }
    
原文地址:https://www.cnblogs.com/lsfv/p/10198538.html