数据结构和算法(26)之二叉排序树

学习数据结构和算法的日常Demo

二叉排序树基本介绍:

在这里插入图片描述

二叉排序树的创建和遍历

public class TreeNode {
    int value;
    TreeNode left;
    TreeNode right;

    public TreeNode(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    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;
    }

    @Override
    public String toString() {
        return "TreeNode{" +
                "value=" + value +
                '}';
    }

    // 前序遍历
    public void preOrder() {
        System.out.print(this.value + " ");
        if (this.left != null) {
            this.left.preOrder();
        }
        if (this.right != null) {
            this.right.preOrder();
        }
    }

    // 中序遍历
    public void infixOrder() {
        // 递归左子树
        if (this.left != null) {
            this.left.infixOrder();
        }
        // 输出父节点
        System.out.print(this.value + " ");
        // 递归右子树
        if (this.right != null) {
            this.right.infixOrder();
        }
    }

    // 后序遍历
    public void postOrder() {
        // 递归左子树
        if (this.left != null) {
            this.left.postOrder();
        }
        // 递归右子树
        if (this.right != null) {
            this.right.postOrder();
        }
        // 输出父节点
        System.out.print(this.value + " ");
    }
	// 递归添加节点
    public void add(TreeNode node) {
        if (node == null) {
            return;
        }
        // 判断传入的节点的值与当前子树根节点的值的关系
        // 小于,往左添加
        if (node.value < this.value) {
            if (this.left == null) {
                // 左子树为空直接添加
                this.left = node;
            } else {
                // 向左子树递归则添加
                this.left.add(node);
            }
        } else {
            // 大于等于往右添加
            if (this.right == null) {
                // 右子树为空直接则添加
                this.right = node;
            } else {
                // 向右子树递归添加
                this.right.add(node);
            }
        }
    }

    // 查找指定节点
    public TreeNode search(int value) {
        if (value == this.value) {
            return this;
        } else if (this.left != null && value < this.value) {
            return this.left.search(value);
        } else if (this.right != null && value >= this.value) {
            return this.right.search(value);
        } else {
            return null;
        }
    }

	// 查找指定节点的父节点
    public TreeNode searchParent(int value) {
        if ((this.left != null && this.left.value == value) || (this.right != null && this.right.value == value)) {
            return this;
        } else {
            if (this.left != null && value < this.value) {
                // 如果查找的值小于当前节点的值
                return this.left.searchParent(value);
            } else if (this.right != null && value >= this.value) {
                // 如果查找的值大于等于当前节点的值
                return this.right.searchParent(value);
            } else {
                return null;    // 找不到
            }
        }
    }
}

// 树操作类
public class BinarySortTree {
    private TreeNode root;

    public TreeNode getRoot() {
        return root;
    }

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

    // 前序遍历
    public void preOrder() {
        if (root != null) {
            root.preOrder();
        } else {
            System.out.println("二叉树为空!");
        }
    }

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

    public void postOrder() {
        if (root != null) {
            root.postOrder();
        } else {
            System.out.println("二叉树为空!");
        }
    }

    // 递归添加
    public void add(TreeNode node) {
        if (root == null) {
            root = node;
        } else {
            root.add(node);
        }
    }

    // 查找指定节点
    public TreeNode search(int value) {
        if (root == null) {
            return null;
        } else {
            return root.search(value);
        }
    }

    // 查找指定节点的父节点
    public TreeNode searchParent(int value) {
        if (root == null) {
            return null;
        } else {
            return root.searchParent(value);
        }
    }
}

// 测试类
public class BinarySortTreeDemo {
    public static void main(String args[]) {
        int[] arr = {7, 3, 10, 12, 5, 1, 9};
        BinarySortTree sortTree = new BinarySortTree();
        // 循环添加节点到树
        // 按照规则构成二叉排序树
        for (int i = 0; i < arr.length; i++) {
            sortTree.add(new TreeNode(arr[i]));
        }
        sortTree.add(new TreeNode(2));
        /*
                7
             3       10
          1    5   9   12
           2
         */

        sortTree.preOrder();
        System.out.println("前序遍历");
        System.out.println("测试查找某节点:" + sortTree.search(5));
        System.out.println("测试查找某节点的父节点:" + sortTree.searchParent(5));
 	}
 }

在这里插入图片描述

二叉排序树的删除

在这里插入图片描述

思路分析

在这里插入图片描述
在这里插入图片描述

情况三分析图示

在这里插入图片描述

代码实现
// TreeNode.class
 // 返回某右节点的左分叉中的最小值(即最底部的左叶子节点)
    public int deleteRightTree(TreeNode node){
        TreeNode treeNode= node;
        // 循环查找左节点,找到最小值
        while (treeNode.left !=null){
            treeNode = treeNode.left;
        }
        // 删除最小节点
        delete(treeNode.value);
        // 返回最小值
        return treeNode.value;
    }

    // 删除节点
    public void delete(int value) {
        // 获取要删除的节点
        TreeNode treeNode = search(value);
        if (treeNode == null) {
            System.out.println("找不到要删除的节点");
            return;
        }
        // 找要删除节点的父节点
        TreeNode parent = searchParent(value);
        // 1.待删除的节点是叶子节点
        if (treeNode.left == null && treeNode.right == null) {
            // 判断要删除的叶子节点是它父节点的左还是右节点
            // 此处必须判断value,如果父节点的左右子树都存在,就得依靠value来判断,否则会误删
            //   3
            // 1   5
            if (parent.left != null && parent.left.value == value) {
                parent.left = null;
            } else if (parent.right != null && parent.right.value == value) {
                parent.right = null;
            }
        } else if (treeNode.left != null && treeNode.right != null) {
            // 2.待删除的节点存在左右子树
            // 遍历待删节点的右子树,在左分支中找到最小value替换待删节点的value
            // 替换后,仍满足二叉排序树
            int minVal = deleteRightTree(treeNode.right);
            treeNode.value = minVal;
        } else {
            // 3.待删除的节点存在一颗子树
            // 判断待删除节点是其父节点的左还是右节点
            if (parent.left.value == value) {
                parent.left = (treeNode.left == null ? treeNode.right : treeNode.left);
            } else {
                parent.right = (treeNode.left == null ? treeNode.right : treeNode.left);
            }
        }
    }

// BinarySortTree.class
 // 删除节点
    public void delete(int value) {
        if (root == null) {
            return;
        } else {
            if (root.left == null && root.right == null) {
                root = null;
            } else {
                root.delete(value);
            }
        }
    }

// BinarySortTreeDemo.class
/*
                7
            3       10
         1     5   9   12
          2
         */
 System.out.println("------测试删除------");
        sortTree.delete(3);
        System.out.println("删除后:");
        sortTree.preOrder();

在这里插入图片描述

GitHub:数据结构和算法源代码

发布了67 篇原创文章 · 获赞 21 · 访问量 2680

猜你喜欢

转载自blog.csdn.net/qq_44779506/article/details/105167896