数据结构(java语言描述)树(二叉树)的构建和遍历操作

二叉树:度为二的,分左右孩子的树。

树结点的结构:

package tree;
public class BitreeNode {
private Object data;//树结点的数据
private BitreeNode lchild,rchild;//树结点的左右孩子结点
public BitreeNode(){//无参构造函数
    this(null);
}
//构造一颗左孩子和右孩子都为空的二叉树结点
public BitreeNode(Object data){
    this.data=data;
    this.lchild=null;
    this.rchild=null;
}
//构造一颗数据域和左孩子和右孩子都不为空的二叉树结点
public BitreeNode(Object data,BitreeNode lchild,BitreeNode rchild){
    this.data=data;
    this.lchild=lchild;
    this.rchild=rchild;
}
//三个数据结点的设置
public Object getData(){
    return data;
}
public BitreeNode getlchild(){
    return lchild;
}
public BitreeNode getrchild(){
    return rchild;
}
public  void setData(Object data){
    this.data=data;
}
public  void setlchild(BitreeNode  lchild){
    this.lchild=lchild;
}
public  void setrchild(BitreeNode rchild){
    this.rchild=rchild;
}
}

树的递归和非递归的遍历操作:

原理理解:

package tree;
import queue.Linkqueue;
import  stack.Linkstack;
public class Bitree {
    private BitreeNode root;
    //构造一颗空树
    public Bitree(){
        this.root=null;
    }
    //构造一棵树
    public Bitree(BitreeNode root){
        this.root=root;
    }
    public BitreeNode getRoot(){
        return root;
    }
    public void setRoot(BitreeNode root){
        this.root=root;
    }
    //由先根遍历和中根遍历的顺序建立一颗二叉树的算法
    public Bitree(String preOrder,String inOrder,int preindex,int inIndex,int count){
        
    }

    //
    //二叉树的遍历算法,递归
    /************DLR/LDR/LRD*******************/
    /************特点:结构简单,但时空开销相对较大,从而导致运行效率较低,并且有些程序设计环境不支持递归*******************/
    public void prerootTraverse(BitreeNode t){
        if(t!=null){
            System.out.print(t.getData());//先根遍历。先访问根节点的数据域
            prerootTraverse(t.getlchild());//其次递归遍历左子树
            prerootTraverse(t.getrchild());//最后遍历右子树
        }
    }
    public void InrootTraverse(BitreeNode t){
        if(t!=null){
            InrootTraverse(t.getlchild());//中根遍历。先递归遍历左子树
            System.out.print(t.getData());//其次访问根节点的数据域
            InrootTraverse(t.getrchild());//最后遍历右子树
        }
    }
    public void PostrootTraverse(BitreeNode t){
        if(t!=null){
            InrootTraverse(t.getlchild());//后根遍历。先递归遍历左子树
            InrootTraverse(t.getrchild());//其次遍历右子树
            System.out.print(t.getData());//最后访问根节点的数据域
        }
    }
    //二叉树的遍历算法,非递归
    /************DLR/LDR/LRD
     * @throws Exception *******************/
   //先根遍历借助一个栈来存储右孩子结点
    /************原理:树的根节点入栈,出栈,访问树的根节点,然后访问根节点的左孩子结点,右孩子入栈,
     * 递归遍历左子树**************/
    public void preroottraverse() throws Exception{
        BitreeNode t=root;
        if(t!=null){
        Linkstack s=new Linkstack();//如果树非空,先创建栈,然后根入栈
        s.push(t);
        while(!s.isEmpty()){//当栈顶元素为非空时,将栈顶元素弹出并访问该结点
            t=(BitreeNode)s.pop();//移除栈顶元素并返回其值
            System.out.print(t.getData());
            while(t!=null){
                if(t.getlchild()!=null)
                    System.out.print(t.getlchild().getData());//访问左子树的根节点
                if(t.getrchild()!=null)//右子树根节点入栈
                    s.push(t.getrchild());
                t=t.getlchild();//遍历左子树
            }//while t!=null
        }//while !s.isEmpty
        }//t!=null    
    }
     //中根遍历借助一个栈来存储根结点和所有的n-1层次的左孩子结点 
    /************原理:树的根节点入栈,然后左孩子结点依次入栈,出栈访问,右孩子入栈,。。。
     * **************/
    public void inroottraverse()throws Exception{
        BitreeNode t=root;
        if(t!=null){//树非空,则创建栈表,并将树的根节点入栈
            Linkstack s=new Linkstack();
            s.push(t);
            while(!s.isEmpty()){//若栈非空
                while(s.peek()!=null){//判断栈顶元素不为空
                    s.push(((BitreeNode) s.peek()).getlchild());//栈顶元素的左孩子结点入栈
                }
                s.pop();//非空结点退栈   ??????
                if(!s.isEmpty()){
                    t=(BitreeNode)s.pop();
                    System.out.print(t.getData());
                    s.push(t.getrchild());
                }
            }
        }
    }
       //先根遍历借助一个栈来依次存储左孩子结点,及右孩子
        /************原理:树的根节点入栈,根节点的左孩子结点依次入栈。若最左下角的结点右孩子为空或已经访问则访问该结点,flag
         * 标记为true,否则右孩子入栈flag标记为false,**************/
public void postroottraverse()throws Exception{
    BitreeNode t=root;
    if(t!=null){
        Linkstack s=new Linkstack();//树非空则创建栈链
        s.push(t);//根节点入栈
        Boolean flag;
        BitreeNode p=null;//p指向刚刚被访问的结点
        while(!s.isEmpty()){
            while(s.peek()!=null){
                s.push(((BitreeNode)s.peek()).getlchild());//左孩子入栈
            }
            s.pop();//空结点出栈
            while(!s.isEmpty()){
                t=(BitreeNode)s.peek();
                if(t.getlchild()==null||t.getrchild()==p){
                    System.out.print(t.getData());
                    s.pop();
                    p=t;
                    flag=true;
                }else{
                    s.push(t.getrchild());
                    flag=false;
                }
                if(!flag)
                    break;
            }
        }
    }
}
//层次遍历,借助的是队列,依次根节点入队,当队列不为空时,队首出队,然后出队结点的左孩子和右孩子依次入队。
//即一个出队,则左右孩子入队。。。
public void leveltranverse()throws Exception{
    BitreeNode t=root;
    if(t!=null){
        Linkqueue q=new Linkqueue();//若树非空,建立队列,并将树的根节点先入队
        q.offer(t);
        while(!q.isEmpty()){//若队列非空,输出队首元素,并判断该结点的左右孩子结点,分别入队
            t=(BitreeNode)q.poll();
            System.out.print(t.getData());//每次访问的都是队首元素
            if(t.getlchild()!=null){
                q.offer(t.getlchild());
            }
            if(t.getrchild()!=null)
                q.offer(t.getrchild());
        }
    }
}

}
3.树的创建和遍历

package tree;

public class tree {
    public Bitree createBitree(){
        BitreeNode d=new BitreeNode('D');
        BitreeNode g=new BitreeNode('g');
        BitreeNode h=new BitreeNode('h');
        BitreeNode e=new BitreeNode('e',g,null);
        BitreeNode b=new BitreeNode('b',d,e);
        BitreeNode f=new BitreeNode('f',null,h);
        BitreeNode c=new BitreeNode('c',f,null);
        BitreeNode a=new BitreeNode('a',b,c);
        return new Bitree(a);
    }
    public static void main(String[] args) throws Exception{
        tree tree1=new tree();
        Bitree bitree=tree1.createBitree();
        BitreeNode root=bitree.getRoot();
        System.out.println("(递归)先根遍历序列:");
        bitree.prerootTraverse(root);
        System.out.println();
        System.out.println("(非递归)先根遍历序列:");
        bitree.preroottraverse();
        System.out.println();
        System.out.println("(递归)中根遍历序列:");
        bitree.InrootTraverse(root);
        System.out.println();
        System.out.println("(非递归)中根遍历序列:");
        bitree.inroottraverse();
        System.out.println();
        System.out.println("(递归)后根遍历序列:");
        bitree.PostrootTraverse(root);
        System.out.println();
        System.out.println("(非递归)后根遍历序列:");
       // bitree.postroottraverse();
        System.out.println();
        System.out.println("层次遍历序列:");
        bitree.leveltranverse();
        System.out.println();

    }
}

结果:

(递归)先根遍历序列:
abDegcfh
(非递归)先根遍历序列:
abDegcfh
(递归)中根遍历序列:
Dbgeafhc
(非递归)中根遍历序列:
Dbgeafhc
(递归)后根遍历序列:
Dbgefhca
(非递归)后根遍历序列:

层次遍历序列:
abcDefgh

原文地址:https://www.cnblogs.com/xleer/p/5378885.html