二叉树深度优先和广度优先的两种遍历方式

一、二叉树的深度优先遍历

这种分类下,根据访问根节点的顺序,有先序,中序和后序遍历三种

而这每一种遍历方式又分为递归和循环的两种方式

递归的方式

public class BinaryTree {  
    /** 
     * 二叉树的先序中序后序排序 
     */  
    public Node init() {
         //这里是建立一个二叉树的操作,就略过了 
    }
    
    public void printNode(Node node){  
        System.out.print(node.getData());  
    }  
    public void theFirstTraversal(Node root) {  //先序遍历  
        printNode(root);  
        if (root.getLeftNode() != null) {  //使用递归进行遍历左孩子  
            theFirstTraversal(root.getLeftNode());  
        }  
        if (root.getRightNode() != null) {  //递归遍历右孩子  
            theFirstTraversal(root.getRightNode());  
        }  
    }  
    public void theInOrderTraversal(Node root) {  //中序遍历  
        if (root.getLeftNode() != null) {  
            theInOrderTraversal(root.getLeftNode());  
        }  
        printNode(root);  
        if (root.getRightNode() != null) {  
            theInOrderTraversal(root.getRightNode());  
        }  
    }
    
    
    public void thePostOrderTraversal(Node root) {  //后序遍历  
        if (root.getLeftNode() != null) {  
            thePostOrderTraversal(root.getLeftNode());  
        }  
        if(root.getRightNode() != null) {  
            thePostOrderTraversal(root.getRightNode());  
        }  
        printNode(root);  
    }  
      
    public static void main(String[] args) {  
        BinaryTree tree = new BinaryTree();  
        Node root = tree.init();  
        System.out.println("先序遍历");  
        tree.theFirstTraversal(root);  
        System.out.println("");  
        System.out.println("中序遍历");  
        tree.theInOrderTraversal(root);  
        System.out.println("");  
        System.out.println("后序遍历");  
        tree.thePostOrderTraversal(root);  
        System.out.println("");  
    }  
}

循环的方式(会用到堆栈作为辅助空间)

public class BinaryTree1 { 
     public Node init() {
           //此处建立一颗二叉树的操作,略过
    } 
    
    public void printNode(Node node){  
        System.out.print(node.getData());  
    }
    
    
    public void theFirstTraversal_Stack(Node root) {  //先序遍历  
        Stack<Node> stack = new Stack<Node>();  
        Node node = root;  
        while (node != null || stack.size() > 0) {  //将所有左孩子压栈  
            if (node != null) {   //压栈之前先访问  
                printNode(node);  
                stack.push(node);  
                node = node.getLeftNode();  
            } else {  
                node = stack.pop();  
                node = node.getRightNode();  
            }  
        }  
    }  
      
    public void theInOrderTraversal_Stack(Node root) {  //中序遍历  
        Stack<Node> stack = new Stack<Node>();  
        Node node = root;  
        while (node != null || stack.size() > 0) {  
            if (node != null) {  
                stack.push(node);   //直接压栈  
                node = node.getLeftNode();  
            } else {  
                node = stack.pop(); //出栈并访问  
                printNode(node);  
                node = node.getRightNode(); 
            }  
        }  
    }  
    //后序遍历略微跟上面两种遍历有点不同,会用到两个栈 
    public void thePostOrderTraversal_Stack(Node root) {   //后序遍历  
        Stack<Node> stack = new Stack<Node>();  
        Stack<Node> output = new Stack<Node>();//构造一个中间栈来存储逆后序遍历的结果  
        Node node = root;  
        while (node != null || stack.size() > 0) {  
            if (node != null) {  
                output.push(node);  
                stack.push(node);                 
                node = node.getRightNode();  
            } else {  
                node = stack.pop();               
                node = node.getLeftNode();
            }  
        }  
        System.out.println(output.size());
        while (output.size() > 0) {
            
            printNode(output.pop());  
        }  
    }
    
    public static void main(String[] args) {  
        BinaryTree1 tree = new BinaryTree1();  
        Node root = tree.init();  
        System.out.println("先序遍历");  
        tree.theFirstTraversal_Stack(root);  
        System.out.println("");  
        System.out.println("中序遍历");  
        tree.theInOrderTraversal_Stack(root);  
        System.out.println("");  
        System.out.println("后序遍历");  
        tree.thePostOrderTraversal_Stack(root);  
        System.out.println("");  
    }
}

二、二叉树的广度优先遍历

广度优先会用到队列这个数据结构,并且没有递归的方法

import java.util.ArrayDeque;     
import java.util.Queue;    

public class BinTree {
    private char date;
    private BinTree lchild;   //左孩子
    private BinTree rchild;   //右孩子
    
    private BinTree(char c ){
        date = c;
    }
 
    
    public static void BFSOrder(BinTree T)
    {
        if(T==null) return ;
        Queue<BinTree> queue = new ArrayDeque<BinTree>();    
        //队列小知识:使用offer和poll优于add和remove之处在于它们返回值可以判断成功与否,而不抛出异常
    
        queue.offer(T);              //算法1:根结点进入队列
        while(!queue.isEmpty())      //算法2:若队列非空,循环执行步骤 3-5,否则执行步骤6
        {
            T=queue.poll();          //算法3:将一个结点出队列,并访问该结点
            System.out.print(T.date);
            if(T.lchild!=null)       //算法4:若该结点的左子树为非空,则将该结点的左孩子结点入队列;
                queue.offer(T.lchild);
            if(T.rchild!=null)       //算法5:若该结点的左子树为非空,则将该结点的右孩子结点入队列;
                queue.offer(T.rchild);    
        }
        //步骤6结束
    }
    
    
    //测试主方法
    public static void main(String[] args) {
         BinTree b1 = new BinTree('a');
         BinTree b2 = new BinTree('b');
         BinTree b3 = new BinTree('c');
         BinTree b4 = new BinTree('d');
         BinTree b5 = new BinTree('e');
         BinTree b6 = new BinTree('f');
         BinTree b7 = new BinTree('g');
    
        /**
         *      a 
         *    /   \
         *   b     c
         *  / \   / \
         * d   e f   g
         */
        b1.lchild = b2;
        b1.rchild = b3;
        b2.lchild = b4;
        b2.rchild = b5;
        b3.lchild = b6;
        b3.rchild = b7;
        System.out.println(12121);

        BinTree.BFSOrder(b1);
        System.out.println();    
        }
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值