二叉树(入门)

二叉树(Binary tree)是树形结构的一个重要类型。
二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。

一、二叉树类定义

public class TreeNode {
	//当前节点
    private Integer value;
    //左子树
    private TreeNode left;
    //右子树
    private TreeNode right;
	
	public TreeNode(Integer value, TreeNode left, TreeNode right) {
        this.value = value;
        this.left = left;
        this.right = right;
    }
	
	public TreeNode(){

    }
    /**此处省略get和set方法**/
}

二、二叉排序树

二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),亦称二叉搜索树。是数据结构中的一类。在一般情况下,查询效率比链表结构要高。

根据数组创建二叉排序树:

//创建二叉排序树
public TreeNode create(int[] arr){
     TreeNode treeNode = new TreeNode();
     for(int i:arr){
         treeNode.insert(treeNode,i);
     }
     return treeNode;
 }
//向二叉树插入数据
public void insert(TreeNode treeNode,int value){
    if(treeNode.getValue()==null){
        treeNode.setValue(value);
    }
    //插入左子树
    if(treeNode.getValue()>value){
        if(treeNode.getLeft()==null){
            treeNode.setLeft(new TreeNode(value,null,null));
        }else{
            insert(treeNode.getLeft(),value);
        }
    }
    //插入右子树
    if(treeNode.getValue()<value){
        if(treeNode.getRight()==null){
            treeNode.setRight(new TreeNode(value,null,null));
        }else{
            insert(treeNode.getRight(),value);
        }
    }

}

三、实现二叉树遍历

以下面的二叉树为例:
在这里插入图片描述
遍历顺序:

先序遍历:根节点→左子树→右子树;
中序遍历:左子树→根节点→右子树;
后序遍历:左子树→右子树→根节点;

遍历结果:

先序遍历:A,B,D,C,E,G,F;
中序遍历:B,D,A,E,G,C,F;
后序遍历:D,B,G,E,F,C,A;

3.1 递归实现

3.1.1 先序遍历(前序遍历)

//先序遍历
public  void fristForeach(TreeNode treeNode){
     if(treeNode!=null){
         System.out.println(treeNode.getValue());
         fristForeach(treeNode.getLeft());
         fristForeach(treeNode.getRight());
     }
 }

3.1.2 中序遍历

//中序遍历
public  void midForeach(TreeNode treeNode){
    if(treeNode!=null){
        midForeach(treeNode.getLeft());
        System.out.println(treeNode.getValue());
        midForeach(treeNode.getRight());
    }
}

3.1.3 后序遍历

//后序遍历
public void lastForeach(TreeNode treeNode){
    if(treeNode!=null){
        lastForeach(treeNode.getLeft());
        lastForeach(treeNode.getRight());
        System.out.println(treeNode.getValue());
    }
}

3.2 辅助栈实现

3.2.1 先序遍历

//非递归式实现先序遍历
public void fristIterateForeach(TreeNode treeNode){
    TreeNode t = treeNode;
    //使用栈存储根节点
    Stack<TreeNode> treeNodeStack = new Stack<>();
    while(t!=null||treeNodeStack.size()>0){
        //当前节点不为空时
        if(t!=null){
            //打印根节点
            System.out.println(t.getValue());
            //存储当前节点
            treeNodeStack.push(t);
            //访问左子树
            t =t.getLeft();
        }else{
            //获取父节点
            t= treeNodeStack.pop();
            //获取父节点的右子树
            t = t.getRight();
        }
    }
}

3.2.2 中序遍历

//非递归式实现中序遍历
public void midIterateForeach(TreeNode treeNode){
    TreeNode t = treeNode;
    //使用栈存储根节点
    Stack<TreeNode> treeNodeStack = new Stack<>();
    while(t!=null||treeNodeStack.size()>0){
        //当前节点不为空时
        if(t!=null){
            //存储当前节点
            treeNodeStack.push(t);
            //访问左子树
            t =t.getLeft();
        }else{
            //获取父节点
            t= treeNodeStack.pop();
            //打印根节点
            System.out.print(t.getValue()+" ");
            //获取父节点的右子树
            t = t.getRight();
        }
    }
}

3.2.3 后序遍历
后序遍历的顺序为为:左→右→中,而前序遍历为:中→左→右,其实可以理解为对前序遍历调整为:中→右→左,然后进行反转即可实现后序遍历

//非递归式实现后序遍历
public void lastIterateForeach(TreeNode treeNode){
    //使用链表反向存储节点
    LinkedList<Integer> linkedList = new LinkedList<>();
    TreeNode t = treeNode;
    //使用栈存储根节点
    Stack<TreeNode> treeNodeStack = new Stack<>();
    while(t!=null||treeNodeStack.size()>0){
        //当前节点不为空时
        if(t!=null){
            //打印根节点
            linkedList.add(0,t.getValue());
            //存储当前节点
            treeNodeStack.push(t);
            //访问左子树
            t =t.getRight();
        }else{
            //获取父节点
            t= treeNodeStack.pop();
            //获取父节点的右子树
            t = t.getLeft();
        }
    }

    for(Integer i :linkedList){
        System.out.println(i);
    }
}

四、 二叉树高度

public  int height(TreeNode treeNode){
        if(treeNode==null){
            return 0;
        }

        int leftHeight = height(treeNode.getLeft());
        int rightHeight = height(treeNode.getRight());

        if(leftHeight>rightHeight)
            return (leftHeight+1);
        else
            return (rightHeight+1);

    }

五、叶子节点个数

public int leafCount(TreeNode treeNode){
    int count=0;
    Stack<TreeNode> treeNodeStack = new Stack<>();
    treeNodeStack.push(treeNode);

    while(treeNodeStack.size()>0){
        TreeNode node = treeNodeStack.pop();
        if(node.getRight()==null&&node.getLeft()==null){
            count++;
        }
        if(node.getLeft()!=null){
            treeNodeStack.push(node.getLeft());
        }
        if(node.getRight()!=null){
            treeNodeStack.push(node.getRight());
        }
    }

    return count;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值