数据结构与算法 -- 二叉搜索树(java实现)

package com.huang.test.datastructure;

import java.util.*;

/**
 * 二叉搜索树
 */
abstract class BstData<T> {
    BstData<T> left;
    BstData<T> right;
    BstData<T> parent;
    private T value;

    /**
     * 比较,> 0:则本对象的值大于t2, <0:则本对象的值小于t2, =0:则本对象的值等于t2
     * @param t2
     * @return
     */
    public abstract int compare(T t2);

    public BstData() {

    }

    public BstData(T value) {
        this.value = value;
    }

    public T getValue() {
        return value;
    }

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

class BstUtil<T> {
    private BstData<T> root = null;

    private void addItem(BstData<T> root, BstData<T> data) {
        if (root.compare(data.getValue()) > 0) {
            if (root.left != null) {
                addItem(root.left, data);
            } else {
                data.parent = root;
                root.left = data;
            }
        } else if (root.compare(data.getValue()) < 0) {
            if (root.right != null) {
                addItem(root.right, data);
            } else {
                data.parent = root;
                root.right = data;
            }
        }
    }

    private BstData<T> findItemMin(BstData<T> item) {
        while (item != null && item.left != null) {
            item = item.left;
        }
        return item;
    }

    public BstData<T> getRoot() {
        return root;
    }

    /**
     * 添加值
     * @param data
     */
    public void add(BstData<T> data) {
        if (root == null) {
            root = data;
            root.parent = null;
        } else {
            addItem(root, data);
        }
    }

    /**
     * 寻找最小值
     * @return
     */
    public BstData<T> min() {
        return findItemMin(root);
    }

    /**
     * 寻找最大值
     * @return
     */
    public BstData<T> max() {
        BstData<T> right = root;
        while (right != null && right.right != null) {
            right = right.right;
        }
        return right;
    }

    /**
     * 查找某个值
     * @param value
     * @return
     */
    public BstData<T> find(T value) {
        BstData<T> result = null;
        BstData<T> item = root;
        while (item != null) {
            int comp = item.compare(value);
            if (comp == 0) {
                result = item;
                break;
            }
            if (comp > 0) {
                item = item.left;
            } else if (comp < 0) {
                item = item.right;
            }
        }
        return result;
    }

    /**
     * 删除某个值
     * @param value
     */
    public void remove(T value) {
        BstData<T> findItem = find(value);
        if (findItem != null) {
            BstData<T> parent = findItem.parent;
            if (findItem.left == null && findItem.right == null)//删除的节点没有左右子节点
            {
                removeNoneChild(parent, findItem);
            } else if (findItem.left != null && findItem.right == null)//删除的节点只有左节点
            {
                removeHasLeftChild(parent, findItem);
            } else if (findItem.left == null && findItem.right != null)//删除的节点只有右节点
            {
                removeHasRightChild(parent, findItem);
            } else if (findItem.left != null && findItem.right != null)//删除的节点有左右子节点
            {
                removeHasTwoChild(parent, findItem);
            }
        }
    }

    /**
     * 删除的节点有左右两个子节点
     * @param findItem
     * @return
     */
    private void removeHasTwoChild(BstData<T> parent, BstData<T> findItem) {
        BstData<T> newChildRoot = getNewRootWhenHasTwoChild(findItem);
        if (parent == null) {
            root = newChildRoot;
        } else {
            newChildRoot.parent = parent;
            if (parent.left == findItem) {
                parent.left = newChildRoot;
            } else if (parent.right == findItem) {
                parent.right = newChildRoot;
            }
        }
    }

    /**
     * 获取删除的节点有左右两个子节点后新的替换节点
     * @param findItem
     * @return
     */
    private BstData<T> getNewRootWhenHasTwoChild(BstData<T> findItem) {
        BstData<T> rightMin = findItemMin(findItem.right);
        if (rightMin == findItem.right) {
            rightMin.left = findItem.left;
            findItem.left.parent = rightMin;
        } else {

            if (rightMin.right == null) {
                rightMin.parent.left = null;
            } else {
                rightMin.parent.left = rightMin.right;
                rightMin.right.parent = rightMin.parent;
            }

            rightMin.left = findItem.left;
            findItem.left.parent = rightMin;

            rightMin.right = findItem.right;
            findItem.right.parent = rightMin;
        }
        return rightMin;
    }

    /**
     * 删除的节点只有右子节点
     * @param parent
     * @param findItem
     */
    private void removeHasRightChild(BstData<T> parent, BstData<T> findItem) {
        BstData<T> newChildRoot = findItem.right;
        if (parent == null) {
            root = newChildRoot;
            root.parent = null;
        } else {
            findItem.right.parent = parent;
            if (parent.left == findItem) {
                parent.left = newChildRoot;
            } else if (parent.right == findItem) {
                parent.right = newChildRoot;
            }
        }
    }

    /**
     * 删除的节点只有左子节点
     * @param parent
     * @param findItem
     */
    private void removeHasLeftChild(BstData<T> parent, BstData<T> findItem) {
        BstData<T> newChildRoot = findItem.left;
        if (parent == null) {
            root = newChildRoot;
            root.parent = null;
        } else {
            findItem.left.parent = parent;
            if (parent.left == findItem) {
                parent.left = newChildRoot;
            } else if (parent.right == findItem) {
                parent.right = newChildRoot;
            }
        }
    }

    /**
     * 删除的节点没有子节点
     * @param parent
     * @param findItem
     */
    private void removeNoneChild(BstData<T> parent, BstData<T> findItem) {
        if (parent == null)//删除根节点
        {
            root = null;
        } else if (parent.left == findItem)//删除的节点是其父节点的左节点
        {
            parent.left = null;
        } else if (parent.right == findItem)//删除的节点是其父节点的右节点
        {
            parent.right = null;
        }
    }

    /**
     * 前序遍历
     */
    private void preorderItemTraversal(ArrayList<BstData<T>> list, BstData<T> item)
    {
        if(item != null)
        {
            list.add(item);
            preorderItemTraversal(list, item.left);
            preorderItemTraversal(list, item.right);
        }

    }

    /**
     * 中序遍历
     */
    private void inorderItemTraversal(ArrayList<BstData<T>> list, BstData<T> item)
    {
        if(item != null)
        {
            inorderItemTraversal(list, item.left);
            list.add(item);
            inorderItemTraversal(list, item.right);
        }
    }

    /**
     * 后序遍历
     */
    private void postorderItemTraversal(ArrayList<BstData<T>> list, BstData<T> item)
    {
        if(item != null)
        {
            postorderItemTraversal(list, item.left);
            postorderItemTraversal(list, item.right);
            list.add(item);
        }
    }

    /**
     * 前序遍历
     */
    public ArrayList<BstData<T>> preorderTraversal()
    {
        ArrayList<BstData<T>> list = new ArrayList<>();
        preorderItemTraversal(list, root);
        return list;
    }

    /**
     * 中序遍历
     */
    public ArrayList<BstData<T>>  inorderTraversal()
    {
        ArrayList<BstData<T>> list = new ArrayList<>();
        inorderItemTraversal(list, root);
        return list;
    }

    /**
     * 后序遍历
     */
    public ArrayList<BstData<T>> postorderTraversal()
    {
        ArrayList<BstData<T>> list = new ArrayList<>();
        postorderItemTraversal(list, root);
        return list;
    }

    /**
     * 深度优先遍历
     * @return
     */
    public ArrayList<BstData<T>> depthFirstTraversal() {
        ArrayList<BstData<T>> list = new ArrayList<>();
        Stack<BstData<T>> stack = new Stack<>();
        stack.push(root);
        while (!stack.isEmpty())
        {
            BstData<T> item = stack.pop();
            if(item != null) {
                list.add(item);
                BstData<T> left = item.left;
                BstData<T> right = item.right;
                if (right != null)
                {
                    stack.push(right);
                }
                if(left != null)
                {
                    stack.push(left);
                }
            }
        }
        return list;
    }

    /**
     * 广度优先遍历
     * @return
     */
    public ArrayList<BstData<T>> breathFirstTraversal() {
        ArrayList<BstData<T>> list = new ArrayList<>();
        LinkedList<BstData<T>> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty())
        {
            BstData<T> item = queue.pop();
            if(item != null)
            {
                list.add(item);
                BstData<T> left = item.left;
                BstData<T> right = item.right;
                if(left != null)
                {
                    queue.offer(left);
                }
                if(right != null)
                {
                    queue.offer(right);
                }
            }
        }
        return list;
    }


}

class BstIntData extends BstData<Integer> {
    public BstIntData() {

    }

    public BstIntData(Integer intv) {
        super(intv);
    }

    @Override
    public int compare(Integer t2) {
        return getValue() - t2;
    }

    @Override
    public String toString() {
        return "value:" + getValue();
    }
}

public class BinarySearchTreeTest {
    public static void main(String[] args) {
        BstUtil<Integer> bstUtil = new BstUtil<>();
        BstIntData intData1 = new BstIntData(100);
        BstIntData intData2 = new BstIntData(300);
        BstIntData intData3 = new BstIntData(250);
        BstIntData intData4 = new BstIntData(350);
        BstIntData intData5 = new BstIntData(200);
        BstIntData intData6 = new BstIntData(225);
        BstIntData intData7 = new BstIntData(215);
        BstIntData intData8 = new BstIntData(340);

        bstUtil.add(intData1);
        bstUtil.add(intData2);
        bstUtil.add(intData3);
        bstUtil.add(intData4);
        bstUtil.add(intData5);
        bstUtil.add(intData6);
        bstUtil.add(intData7);
        bstUtil.add(intData8);

        BstData<Integer> root = bstUtil.getRoot();
        BstData<Integer> min = bstUtil.min();
        BstData<Integer> max = bstUtil.max();

        ArrayList<BstData<Integer>> prelist = bstUtil.preorderTraversal();//100, 300, 250, 200, 225, 215, 350, 340
        ArrayList<BstData<Integer>> inlist = bstUtil.inorderTraversal();//100, 200, 215, 225, 250, 300,340, 350
        ArrayList<BstData<Integer>> postlist = bstUtil.postorderTraversal();//215, 225, 200, 250, 340, 350, 300, 100

        ArrayList<BstData<Integer>> breathList = bstUtil.breathFirstTraversal(); //100, 300, 250, 350, 200, 340, 225, 215
        ArrayList<BstData<Integer>> depthList = bstUtil.depthFirstTraversal();//100, 300, 250, 200, 225, 215, 350, 340
        int i = 0;
        i++;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值