二叉树前中后序遍历、查找和删除

这篇博客介绍了二叉树的前序、中序和后序遍历的实现,包括在节点类和二叉树类中添加相应的方法。此外,还实现了基于前中后序遍历的搜索功能,并通过实例测试了查找效率。接着,展示了如何在二叉树中删除节点。最后,探讨了顺序存储二叉树的概念,给出了前中后序遍历的顺序存储实现,并通过主方法进行了测试。顺序存储二叉树在堆排序等场景中有实际应用。
摘要由CSDN通过智能技术生成

首先,我们定义树结点

class TreeNode{
    private int no;
    private String name;
    private TreeNode left;
    private TreeNode right;

    public TreeNode(int no, String name) {
        this.no = no;
        this.name = name;
    }

    @Override
    public String toString() {
        return "TreeNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public TreeNode getLeft() {
        return left;
    }

    public void setLeft(TreeNode left) {
        this.left = left;
    }

    public TreeNode getRight() {
        return right;
    }

    public void setRight(TreeNode right) {
        this.right = right;
    }

    public void prefixOrder(){
        System.out.println(this);
        if (this.left!=null){
            this.left.prefixOrder();
        }
        if (this.right!=null){
            this.right.prefixOrder();
        }
    }

    public void infixOrder(){
        if (this.left!=null){
            this.left.infixOrder();
        }
        System.out.println(this);
        if (this.right!=null){
            this.right.infixOrder();
        }
    }

    public void suffixOrder(){
        if (this.left!=null){
            this.left.suffixOrder();
        }
        if (this.right!=null){
            this.right.suffixOrder();
        }
        System.out.println(this);
    }
}

其次,定义二叉树 

class BinaryTree{
    private TreeNode root;

    public void setRoot(TreeNode root) {
        this.root = root;
    }

    public void prefixOrder(){
        if (this.root!=null){
            this.root.prefixOrder();
        }else {
            System.out.println("二叉树为空,无法遍历!");
        }
    }

    public void infixOrder(){
        if (this.root!=null){
            this.root.infixOrder();
        }else {
            System.out.println("二叉树为空,无法遍历!");
        }
    }

    public void suffixOrder(){
        if (this.root!=null){
            this.root.suffixOrder();
        }else {
            System.out.println("二叉树为空,无法遍历!");
        }
    }
}

接着,我们在主方法中测试上面书写的遍历是否正确

public class BinaryTreeDemo {
    public static void main(String[] args) {
        BinaryTree binaryTree = new BinaryTree();
        TreeNode root = new TreeNode(1, "张三");
        TreeNode node2 = new TreeNode(2, "李四");
        TreeNode node3 = new TreeNode(3, "王五");
        TreeNode node4 = new TreeNode(4, "赵六");
        TreeNode node5 = new TreeNode(5, "田七");
        root.setLeft(node2);
        root.setRight(node3);
        node3.setLeft(node5);
        node3.setRight(node4);
        binaryTree.setRoot(root);
        System.out.println("前序遍历:");
        binaryTree.prefixOrder();
        System.out.println("中序遍历");
        binaryTree.infixOrder();
        System.out.println("后序遍历");
        binaryTree.suffixOrder();
    }
}

预想的前序遍历结果:张三->李四->王五->田七->赵六

预想的中序遍历结果:李四->张三->田七->王五->赵六  

预想的后序遍历结果:李四->田七->赵六->王五->张三

前中后序查找元素

在树节点类TreeNode上添加前中后排序遍历查找方法

public TreeNode prefixOrderSearch(int no) {
        System.out.println("进入前序遍历查找~~");
        if (this.no == no) {
            return this;
        }
        TreeNode resNode = null;
        if (this.left != null) {
            resNode = this.left.prefixOrderSearch(no);
        }
        if (resNode != null) {
            return resNode;
        }
        if (this.right != null) {
            resNode = this.right.prefixOrderSearch(no);
        }
        return resNode;
    }

    public TreeNode infixOrderSearch(int no) {
        TreeNode resNode = null;
        if (this.left != null) {
            resNode = this.left.infixOrderSearch(no);
        }
        if (resNode != null) {
            return resNode;
        }
        System.out.println("进入中序遍历查找~~");
        if (this.no == no) {
            return this;
        }
        if (this.right != null) {
            resNode = this.right.infixOrderSearch(no);
        }
        return resNode;
    }

    public TreeNode suffixOrderSearch(int no) {
        TreeNode resNode = null;
        if (this.left != null) {
            resNode = this.left.suffixOrderSearch(no);
        }
        if (resNode != null) {
            return resNode;
        }
        if (this.right != null) {
            resNode = this.right.suffixOrderSearch(no);
        }
        if (resNode != null) {
            return resNode;
        }
        System.out.println("进入后序遍历查找~~");
        if (this.no == no) {
            return this;
        }
        return resNode;
    }

在二叉树类BinaryTree上也添加前中后序遍历查找方法 

public TreeNode prefixOrderSearch(int no){
        if (root!=null){
            return root.prefixOrderSearch(no);
        }else {
            return null;
        }
    }

    public TreeNode infixOrderSearch(int no){
        if (root!=null){
            return root.infixOrderSearch(no);
        }else {
            return null;
        }
    }

    public TreeNode suffixOrderSearch(int no){
        if (root!=null){
            return root.suffixOrderSearch(no);
        }else {
            return null;
        }
    }

最后,我们对以上前中后序遍历查找进行测试,eg查找5元素(存在)

//        System.out.println("前序遍历查找~~");
//        TreeNode resNode = binaryTree.prefixOrderSearch(5);

//        System.out.println("中序遍历查找~~");
//        TreeNode resNode = binaryTree.infixOrderSearch(5);
    
        System.out.println("后序遍历查找~~");
        TreeNode resNode = binaryTree.suffixOrderSearch(5);
        if (resNode!=null){
            System.out.printf("找到了,信息为no=%d name=%s",resNode.getNo(),resNode.getName());
        }else {
            System.out.printf("没有找到no=%d 的人物",5);
        }

总结:后序遍历查找2次,中序遍历查找3次,前序遍历查找4次

删除节点

在树节点类TreeNode上添加删除节点方法

public void delNode(int no) {
        if (this.left != null && this.left.no == no) {
            this.left = null;
            return;
        }
        if (this.right != null && this.right.no == no) {
            this.right = null;
            return;
        }
        if (this.left != null) {
            this.left.delNode(no);
        }
        if (this.right != null) {
            this.right.delNode(no);
        }
    }

 在二叉树类BinaryTree上也添加删除节点方法 

public void delNode(int no) {
        if (root != null) {
            if (root.getNo() == no) {
                root = null;
            } else {
                root.delNode(no);
            }
        } else {
            System.out.println("该树为空树,无法删除!");
        }
    }

在main方法上测试,运行结果如下:

System.out.println("删除前,前序遍历");
        binaryTree.prefixOrder();
        binaryTree.delNode(3);
        System.out.println("删除后,前序遍历");
        binaryTree.prefixOrder();

顺序存储二叉树特点

 定义数组二叉树类

class ArrBinaryTree {
    private int[] arr;

    public ArrBinaryTree(int arr[]) {
        this.arr = arr;
    }

    public void preOrder(){
        this.preOrder(0);
    }

    public void midOrder(){
        this.midOrder(0);
    }

    public void postOrder(){
        this.postOrder(0);
    }

    /**
     * 编写一个方法,完成顺序存储二叉树的前序遍历
     *
     * @param index 数组的下标
     */
    public void preOrder(int index) {
        if (arr == null || arr.length == 0) {
            System.out.println("数组为空,不能按照二叉树的前序遍历");
        }
        //输出当前这个元素
        System.out.print(arr[index]+" ");
        //向左递归遍历
        if ((2 * index + 1) < arr.length) {
            preOrder(2 * index + 1);
        }
        //向右递归遍历
        if ((2 * index + 2) < arr.length) {
            preOrder((2 * index + 2));
        }
    }

    /**
     * 编写一个方法,完成顺序存储二叉树的中序遍历
     *
     * @param index 数组的下标
     */
    public void midOrder(int index) {
        if (arr == null || arr.length == 0) {
            System.out.println("数组为空,不能按照二叉树的前序遍历");
        }
        //向左递归遍历
        if ((2 * index + 1) < arr.length) {
            midOrder(2 * index + 1);
        }
        //输出当前这个元素
        System.out.print(arr[index]+" ");
        //向右递归遍历
        if ((2 * index + 2) < arr.length) {
            midOrder((2 * index + 2));
        }
    }

    /**
     * 编写一个方法,完成顺序存储二叉树的后序遍历
     *
     * @param index 数组的下标
     */
    public void postOrder(int index) {
        if (arr == null || arr.length == 0) {
            System.out.println("数组为空,不能按照二叉树的前序遍历");
        }
        //向左递归遍历
        if ((2 * index + 1) < arr.length) {
            postOrder(2 * index + 1);
        }
        //向右递归遍历
        if ((2 * index + 2) < arr.length) {
            postOrder((2 * index + 2));
        }
        //输出当前这个元素
        System.out.print(arr[index]+" ");
    }
}

主方法测试类

public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7};
        ArrBinaryTree arrBinaryTree = new ArrBinaryTree(arr);
        arrBinaryTree.preOrder();// 1 2 4 5 3 6 7
        System.out.println();
        arrBinaryTree.midOrder();
        System.out.println();
        arrBinaryTree.postOrder();
    }

 

总结:顺序存储二叉树的实际应用是堆排序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值