数据结构--二叉排序树

1 二叉排序树
1.1二叉排序树又称二叉查找树。
根节点的左子树一定小于根节点中的value值而下于右子树中的value。
二叉排序树:或者是一棵空树,或者是具有下列性质的二叉树:

  1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

  2. 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

  3. 它的左、右子树也分别为二叉排序树。
    1.2 尝试写类似TreeMap的集合;
    每条映射的结构为

static final class Entry<V, K> implements Map.Entry<K, V> {

        /**
         * 存储的key值
         */
        private K key;

        /**
         * 存储的value值
         */
        private V value;

        /**
         * 指向左子数
         */
        private Entry<K, V> left = null;

        /**
         * 指向右子数
         */
        private Entry<K, V> right = null;

        /**
         * 指向父节点
         */
        private Entry<V, K> parentRoot = null;

        public Entry(K key, V value, Entry<V, K> parentRoot) {
            this.key = key;
            this.value = value;
            this.parentRoot = parentRoot;
        }

继承Map中的Entry集合
核心代码:
插入函数

/**
     * 将数据插入到树的指定位置
     * 说明:记录父节点,通过他的左右节点,如果节点为空,value值满足二叉排序树的特征,
     * 则插入,否则递归查找适合的位置
     * @param parentRoot
     *            父节点
     * @param key
     *            待插入节点key值
     * @param value
     *            待插入节点value值
     */
    public void insertIntoTree(Entry<Integer, Integer> parentRoot, Integer key,
            Integer value) {
        if (parentRoot != null) {
            if (parentRoot.getKey() > key) {// 左节点
                if (parentRoot.left == null) {// 左节点可进行插入
                    parentRoot.left = new Entry<Integer, Integer>(key, value,
                            parentRoot);
                } else {// 向左节点下搜索可插入的节点
                    insertIntoTree(parentRoot.left, key, value);
                }
            } else if (parentRoot.getKey() < key) {// 右节点
                if (parentRoot.right == null) {// 右节点可插入
                    parentRoot.right = new Entry<Integer, Integer>(key, value,
                            parentRoot);
                } else {// 向右节点下搜索可插入的节点
                    insertIntoTree(parentRoot.right, key, value);
                }
            } else {// 当出现重复的key值重置value值
                parentRoot.setValue(value);
            }
        } else {
            // 生成最高根节点
            this.root = new Entry<Integer, Integer>(key, value, null);
        }
    }

根据key值查找节点:

/**
     * 根据key查找对应的节点 当前树无节点时,返回null
     * 
     * @param root
     *            根节点,传入的根节点是相对的
     * @param key
     *            要查找的节点的key值
     * @return 节点
     */
    public Entry<Integer, Integer> getEntry(Entry<Integer, Integer> root,
            Integer key) {
        if (root == null) {// 当前所在的节点为空,
            return null;
        } else {
            if (root.getKey() > key) {// 当前节点的key值大于key,向左递归
                return getEntry(root.left, key);
            } else if (root.getKey() == key) {// 当前节点即为要查找的节点
                return root;
            } else {// 当前节点的key值小于key,向右递归查找
                return getEntry(root.right, key);
            }
        }
    }

删除节点:

/**
     * 删除指定的映射
     * 
     * @param key
     *            键值对的key
     */
    public void remove(Integer key) {
        Entry entry = get(key);//要删除的节点
        Entry entryPar = getParentEntry(this.root, key);//要删除的节点的父节点
        if ((entry.left == null) && (entry.right == null)) {// 删除的节点为叶子节点
            // 判断该叶子节点为父节点的左节点还是右节点
            if (entryPar.left == entry) {
                // 删除的节点为左节点
                // 将父节点指向左节点的指针指为null
                entryPar.left = null;
            } else if (entryPar.right == entry) {
                // 删除的节点为右节点
                // 将父节点指向右节点的指针指为null
                entryPar.right = null;
            } else {

            }
        } else if (entry.left != null && entry.right == null) {// 删除的节点只有左节点
            entryPar.left = entry.left;
        } else if (entry.left == null && entry.right != null) {// 删除的节点只有右节点
            entryPar.right = entry.right;
        } else {// 左右节点均不为空
                // 在该节点的右节点中找到value最小的节点,即为右节点中最左边的位置
            Entry<Integer, Integer> minEntry = entry.right;// 最小value值的节点
            Entry<Integer, Integer> minEntryPar = minEntry;// 最小value值的节点父节点
            while (minEntry.left != null) {
                minEntryPar = minEntry;
                minEntry = minEntry.left;
            }

            entry.value = minEntry.value;// 替换值
            if (minEntry == minEntryPar) {// 特殊情况,被删节点的右节点即是最小value值的节点,
                //即最小的节点没有左节点,只有右节点,并且它的父节点也没有左节点,三个在一条直线上
                entryPar.right = minEntry.right;
            } else {// 一般情况,最小节点只有右节点。没有左节点,直接嫁接
                minEntryPar.left = minEntry.right;
            }
        }
    }

未完待续。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值