• 数据结构(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

  • 相关阅读:
    拉格朗日乘子基本概念
    "模式识别与机器学习"读书笔记——2.3(2)
    [raw]人工智能方向调查
    Android !No Launcher activity found!错误
    [raw]ubuntu在当前目录右键打开终端
    Android, 读取大型文件报错
    Blueman Ubuntu的蓝牙管理器
    VMware下Ubuntu8.04 方向键失效的解决方法
    无线中间人攻击初探
    【经验】短接 Flash 解决二次量产金士顿 DTI G2 4GB U盘(群联PS225139)问题
  • 原文地址:https://www.cnblogs.com/xleer/p/5378885.html
Copyright © 2020-2023  润新知