数据结构--二叉树

二叉树的实现、广度优先遍历和递归、非递归的深度优先遍历,思路在注释中:

package 二叉树;

import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;

public class BinaryTree<E> {
    public static class TreeNode<E>{
        TreeNode<E> leftChild;
        TreeNode<E> rightChild;
        E value;
        public TreeNode(E value, TreeNode<E> leftChild, TreeNode<E> rightChild){
            this.value = value;
            this.leftChild = leftChild;
            this.rightChild = rightChild;
        }
    }
    TreeNode<E> root;
    public BinaryTree(TreeNode<E> root){
        this.root = root;
    }
    public void breadFirstTravel(){
        Queue<TreeNode<E>> queue = new LinkedList<TreeNode<E>>();
        queue.offer(root);
        while(!queue.isEmpty()){
            TreeNode<E> currentNode = queue.poll();
            System.out.print(currentNode.value+" ");
            if(currentNode.leftChild!=null)
                queue.add(currentNode.leftChild);
            if(currentNode.rightChild!=null)
                queue.add(currentNode.rightChild);
        }
        System.out.println();
    }
    public void preRootTravalWithRecursion(){
        preRootTravalWithRecursion(root);
        System.out.println();
    }
    private void preRootTravalWithRecursion(TreeNode<E> node){
        if(node!=null){
            System.out.print(node.value+" ");
            preRootTravalWithRecursion(node.leftChild);
            preRootTravalWithRecursion(node.rightChild);
        }
    }
    public void inRootTravalWithRecursion(){
        inRootTravalWithRecursion(root);
        System.out.println();
    }
    private void inRootTravalWithRecursion(TreeNode<E> node){
        if(node!=null){
            inRootTravalWithRecursion(node.leftChild);
            System.out.print(node.value+" ");
            inRootTravalWithRecursion(node.rightChild);
        }
    }
    public void postRootTravalWithRecursion(){
        postRootTravalWithRecursion(root);
        System.out.println();
    }
    private void postRootTravalWithRecursion(TreeNode<E> node){
        if(node!=null){
            postRootTravalWithRecursion(node.leftChild);
            postRootTravalWithRecursion(node.rightChild);
            System.out.print(node.value+" ");
        }
    }
    //单栈实现非递归先序遍历 访问节点 右子树入栈 左子树入栈
    public void preRootTravelWithoutRecursion(){
        Deque<TreeNode<E>> deque = new LinkedList<TreeNode<E>>();
        TreeNode<E> temp ;
        if(root!=null){
            deque.addLast(root);
            while(!deque.isEmpty()){
                //访问节点
                temp = deque.removeLast();
                System.out.print(temp.value+" ");
                //右子树入栈
                if(temp.rightChild!=null)
                    deque.addLast(temp.rightChild);
                //左子树入栈
                if(temp.leftChild!=null)
                    deque.addLast(temp.leftChild);
            }
            System.out.println();
        }
    }
    //单栈非递归实现二叉树的中序遍历
    public void inRootTravelWithoutRecursion(){
        Deque<TreeNode<E>> deque = new LinkedList<TreeNode<E>>();
        TreeNode<E> temp = root;
        while(temp!=null||!deque.isEmpty()){
            //当前节点所有左侧子节点压入栈
            while(temp!=null){
                deque.addLast(temp);
                temp = temp.leftChild;
            }
            //访问当前结点 转向右子树
            if(!deque.isEmpty()){
                temp = deque.removeLast();
                System.out.print(temp.value+" ");
                //转向右子树
                temp = temp.rightChild;
            }
        }
        System.out.println();
    }
    //非递归单栈后序遍历
    public void postRootTravelWithoutRecursion(){
        Deque<TreeNode<E>> deque = new LinkedList<TreeNode<E>>();  
        TreeNode<E> pointer = root;
        TreeNode<E> preNode = null;//存放上一个被访问过的元素    
        while(pointer!=null){  
            for(;pointer.leftChild!=null;pointer = pointer.leftChild){//将所有有左子树的结点压入栈中    
                deque.addLast(pointer);
            }  
            while(pointer!=null && (pointer.rightChild==null||preNode==pointer.rightChild)){//右子树被访问过了或者右子树为空  
                System.out.print(pointer.value+" ");  
                preNode = pointer;//把pointer置为上一个访问节点  
                if(deque.isEmpty())  
                {  
                    return;  
                }  
                pointer = deque.removeLast();  
            }  
            deque.addLast(pointer);  
            pointer = pointer.rightChild;  
        }
        System.out.println();
    }
}

对于广度优先遍历,借助队列来实现,从根开始,将根入队列,然后如果左孩子不为空,左孩子入队列,右孩子不为空,右孩子入队列。然后出对列,继续访问,直到队列空。

对于递归实现的深度优先遍历,每当要访问一个结点,便对这个结点的左孩子右孩子进行递归深度优先遍历,先序、中序、后序只不过是对该节点访问、对左孩子递归、对右孩子递归的顺序问题而已。

对于非递归的先序遍历,借助栈来实现。从根开始,访问根结点,将其右子树入栈,然后左子树入栈。弹栈重复上述步骤,直到栈空。

对于非递归的中序遍历,借助栈来实现。对于访问一个结点,将其所有左节点入栈。然后弹栈,访问当前节点,转向栈内结点的右子树,如果这些右子树有左子树,继续入栈这些左结点。重复以上,直到栈空并且当前访问结点为空。

对于非递归的后序遍历,借助栈来实现。将所有有左子树的结点压入栈中,当前结点为最后一个没有左子树的结点,如果当前结点没有右子树或者右子树被访问过,则访问当前结点,将当前结点置为上一次访问的结点,否则当前结点入栈,转向右子树。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值