二叉排序树

概念

    二叉排序树,又称二叉查找树。它或者是一棵空树,或者是具有下列性质的二叉树:
①若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值。
② 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值。
③ 它的左右子树也分别为二叉排序树。

查找、插入和删除操作

package binaryTree;

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

    TreeNode(int val) {
        this.val = val;
    }
}

举例
873621-20180820144928679-461047453.jpg

package binaryTree;

import java.util.ArrayList;
import java.util.Scanner;

public class BST {

    // 若查找成功p指向该数据元素结点,否则p指向查找路径上访问的最后一个结点;
    private static TreeNode p;

    /**
     * 查找操作
     * 
     * 思路:根据二叉排序树的性质,分左右子树进行递归查找;
     * 
     * @param root
     *            当前结点;
     * @param f
     *            当前节点的父结点;
     * @param p
     * 
     * @param key
     *            关键值
     */
    private static boolean BST_search(TreeNode root, TreeNode f, int key) {
        if (root == null) {
            p = f;
            return false;
        } else if (key == root.val) {
            p = root;
            return true;
        } else if (key > root.val) {
            return BST_search(root.right, root, key);
        } else {
            return BST_search(root.left, root, key);
        }
    }

    /**
     * 插入操作;
     * 
     * 思路:先查找原二叉树是否存在,不存在插入,存在则不插入;
     * 
     * @param key
     *            关键值
     */
    private static boolean BST_insert(TreeNode root, int key) {

        p = null;
        if (!BST_search(root, null, key)) { // 不存在,则插入,p是查找的最后一个节点;
            TreeNode node = new TreeNode(key);
            if (p == null) { // 根节点;
                root = node;
            } else if (p.val < key) { // node作为右结点;
                p.right = node;
            } else { // 作为左节点;
                p.left = node;
            }
            return true;
        } else { // 已经存在;
            return false;
        }
    }

    private static void clear() {
        p = null;
    }

    /**
     * 删除操作;
     * 分情况:1、待删除的点为叶子结点(直接删除);2、只有左或者右分支(子承父业);3、左右分支都存在(找中序遍历待删结点的前驱或者后继结点代替);
     * 
     * @param root
     *            当前结点;
     * @param key
     *            关键字;
     * @return
     */
    private static boolean BST_delete(TreeNode root, int key) {
        if (root == null) { // 树为空,则不存在关键字为key的值;
            return false;
        } else {
            if (key == root.val) { // 找到;
                return deleteNode(root);

            } else if (root.val > key) { // 到左子树中去查找;
                return BST_delete(root.left, key);
            } else {// 到右子树中去查找;
                return BST_delete(root.right, key);
            }
        }
    }

    /**
     * 删除结点;
     * 
     * @param root
     * @return
     */
    private static boolean deleteNode(TreeNode root) {
        if (root.left == null && root.right == null) { // 叶子结点;
            root = null;

        } else if (root.left == null) {// 左子树为空,则右子树的根结点代替;
            root = root.right;

        } else if (root.right == null) { // 右子树为空,则左子树的根结点代替;
            root = root.left;

        } else { // 左右子树都存在;
            // 首先找到该结点的中序遍历的前驱结点,即左子树的最右端的结点;
            TreeNode f = root;
            TreeNode p = f.left;// 左子树的根结点;
            while (p.right != null) {
                f = p;
                p = p.right;
            }
            // 找到最终的的前驱f;
            root.val = p.val;
            if (f == root) { // 重新连接q的左子树;
                f.left = p.left;
            } else { // 重新连接q的右子树;
                f.right = p.left;
            }
            p = null;

        }
        return true;
    }

    /**
     * 中序遍历
     * 
     * @param root
     */
    private static void inOrderTraverse(TreeNode root, ArrayList<Integer> list) {
        if (root == null) {
            return;
        }

        inOrderTraverse(root.left, list);
        list.add(root.val);
        inOrderTraverse(root.right, list);

    }

    public static void main(String[] args) {

        TreeNode root = null;
        ArrayList<Integer> list = new ArrayList<Integer>();
        int[] arr = { 80, 56, 92, 34, 60, 86, 101, 22, 49, 58, 72, 42 };

        for (int i : arr) {
            if (root == null) {
                root = new TreeNode(i);// 根节点显示给出单独;;
            } else {
                BST_insert(root, i);
            }
        }

        // 原二叉排序树;
        inOrderTraverse(root, list);
        System.out.println("删除前:"+list);

        // 清空p;
        clear();

        // 删除56这个结点;
        BST_delete(root, 56);

        // 清空List;
        list.clear();
        // 删除后结构没有改变;
        inOrderTraverse(root, list);
        System.out.println("删除结点56后:"+list);

    }
}

运行结果:
873621-20180820145246134-343338225.png

转载于:https://www.cnblogs.com/LynnMin/p/9504446.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值