基于Java的二叉搜索树

支持泛型

// 节点类,画蛇添足版。

public class BSTNode<T extends Comparable<? super T>> {
    private T value;

    public T getValue() {
        return value;
    }

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

    public BSTNode<T> getLeftChild() {
        return leftChild;
    }

    public void setLeftChild(BSTNode<T> leftChild) {
        this.leftChild = leftChild;
    }

    public BSTNode<T> getRightChild() {
        return rightChild;
    }

    public void setRightChild(BSTNode<T> rightChild) {
        this.rightChild = rightChild;
    }

    private BSTNode<T> leftChild;
    private BSTNode<T> rightChild;

    public BSTNode<T> getParent() {
        return parent;
    }

    public void setParent(BSTNode<T> parent) {
        this.parent = parent;
    }

    private BSTNode<T> parent;

    public BSTNode() {
        this.value = null;
        this.leftChild = null;
        this.rightChild = null;
        this.parent = null;
    }

    public BSTNode(T obj) {
        this.value = obj;
        this.leftChild = null;
        this.rightChild = null;
        this.parent = null;
    }

    public BSTNode(T value, BSTNode<T> leftChild, BSTNode<T> rightChild, BSTNode<T> parent) {
        this.value = value;
        this.leftChild = leftChild;
        this.rightChild = rightChild;
        this.parent = parent;
    }

}

// 树类。

import java.util.*;

public class BSTree<T extends Comparable<? super T>> {
    /*
     * 应支持以下操作:
     * 查找节点、插入节点、删除节点
     * 遍历:前序、中序、后序、层序
     * 最小值、最大值、前驱值、后继值
     *
     * 支持泛型
     */

    // 存储头节点
    public BSTNode<T> head;
    // 存储树节点个数
    private int Num;

    // 查找结点
    private BSTNode<T> getNodeByVal(T obj){
        if(this.Num == 0 || this.head == null) return null;
        return this.getNodeByValImpl(obj, this.head);
    }

    private BSTNode<T> getNodeByValImpl(T obj, BSTNode<T> cur){
        if(obj == null || cur == null) return null;
        int res = obj.compareTo(cur.getValue());
        if(res == 0)    return cur;
        else if(res > 0)    return getNodeByValImpl(obj, cur.getRightChild());
        else    return getNodeByValImpl(obj, cur.getLeftChild());
    }

    // 查找操作。根据值得到对象,公有
    public T getValueByVal(T obj){
        return this.getNodeByVal(obj).getValue();
    }

    // 构造函数
    public BSTree(){
        this.Num = 0;
        this.head = null;
        this.preOrderArr = new ArrayList<T>();
        this.inOrderArr = new ArrayList<T>();
        this.posOrderArr = new ArrayList<T>();
        this.levelOrderArr = new ArrayList<T>();
    }

    // 插入节点。成功插入则true,插入失败则false
    public boolean insertNodeByVal(T obj){
        if(this.head == null)   {
            this.head = new BSTNode<T>(obj);
            return true;
        }

        BSTNode<T> cur = this.head;
        while(cur != null){
            int res = obj.compareTo(cur.getValue());
            if(res == 0)    return false;
            else if(res > 0) {
                if (cur.getRightChild() == null){
                    BSTNode<T> newNode = new BSTNode<T>(obj);
                    cur.setRightChild(newNode);
                    newNode.setParent(cur);
                    this.Num++;
                    return true;
                }else{
                    cur = cur.getRightChild();
                }
            }
            else{
                if(cur.getLeftChild() == null){
                    BSTNode<T> newNode = new BSTNode<T>(obj);
                    cur.setLeftChild(newNode);
                    newNode.setParent(cur);
                    this.Num++;
                    return true;
                }else{
                    cur = cur.getLeftChild();
                }
            }
        }
        return false;   // 其实不会执行到
    }

    // 得到当前子树的得到最小值节点
    private BSTNode<T> getMinNode(BSTNode<T> root){
        BSTNode<T> cur = root;
        if(cur == null) return null;
        while(cur.getLeftChild() != null){
            cur = cur.getLeftChild();
        }
        return cur;
    }
    // 得到最大值节点
    private BSTNode<T> getMaxNode(BSTNode<T> root){
        BSTNode<T> cur = root;
        if(cur == null) return null;
        while(cur.getRightChild() != null){
            cur = cur.getRightChild();
        }
        return cur;
    }

    // 删除节点
    public boolean removeNodeByVal(T obj){
        BSTNode<T> cur = this.getNodeByVal(obj);
        if(cur == null)
            return false;
        // 如果是叶节点
        if(cur.getRightChild() == null && cur.getLeftChild() == null){
            BSTNode<T> p = cur.getParent();
            if(p == null) {
                this.head = null;
            }else if(cur == p.getLeftChild()){
                p.setLeftChild(null);
            }else if(cur == p.getRightChild()){
                p.setRightChild(null);
            }
            this.Num--;
        }
        else if(cur.getRightChild() == null && cur.getLeftChild() != null){
            // 左单子树
            BSTNode<T> subRoot = cur.getLeftChild();
            BSTNode<T> replaceNode = getMaxNode(subRoot);
            cur.setValue(replaceNode.getValue());
            BSTNode<T> preplaceNode = replaceNode.getParent();
            BSTNode<T> subReplaceNode = replaceNode.getLeftChild();
            if(subReplaceNode != null) {
                // 如果该最大值有左子树
                subReplaceNode.setParent(preplaceNode);
            }
            if(replaceNode == preplaceNode.getRightChild()){
                // 替换节点是其父结点的右孩子
                preplaceNode.setRightChild(subReplaceNode);
            }else{
                // 替换节点是父结点的左孩子,此时应该直接是cur子孩子
                preplaceNode.setLeftChild(subReplaceNode);
            }
            this.Num--;
        }
        else if(cur.getRightChild() != null){
            // 右单子树 以及 两边子树都有
            BSTNode<T> subRoot = cur.getRightChild();
            BSTNode<T> replaceNode = getMinNode(subRoot);
            cur.setValue(replaceNode.getValue());
            BSTNode<T> preplaceNode = replaceNode.getParent();
            BSTNode<T> subReplaceNode = replaceNode.getRightChild();
            if(subReplaceNode != null){
                subReplaceNode.setParent(preplaceNode);
            }
            if(replaceNode == preplaceNode.getLeftChild()){
                preplaceNode.setLeftChild(subReplaceNode);
            }else{
                preplaceNode.setRightChild(subReplaceNode);
            }
            this.Num--;
        }
//        else if(cur.getRightChild() != null && cur.getLeftChild() != null){
//            // 两边都有,这里采用交换右子树的最小值
//            BSTNode<T> subRoot = cur.getRightChild();
//            BSTNode<T> replaceNode = getMinNode(subRoot);
//            cur.setValue(replaceNode.getValue());
//            BSTNode<T> preplaceNode = replaceNode.getParent();
//        }
        return true;
    }



    private ArrayList<T> preOrderArr;

    // 前序遍历
    public ArrayList<T> preOrderRecur(BSTNode<T> cur){
        preOrderArr.clear();
        this.preOrderRecurImpl(cur);
        return preOrderArr;
    }

    public ArrayList<T> preOrderIter(BSTNode<T> cur){
        preOrderArr.clear();
        this.preOrderIterImpl(cur);
        return preOrderArr;
    }

    private void preOrderRecurImpl(BSTNode<T> cur){
        if(cur == null) return;
        preOrderArr.add(cur.getValue());
        preOrderRecurImpl(cur.getLeftChild());
        preOrderRecurImpl(cur.getRightChild());
    }

    private void preOrderIterImpl(BSTNode<T> cur){
        if(cur == null) return;
        Stack<BSTNode<T>> S = new Stack<BSTNode<T>>();
        while(!S.empty() || cur != null){
            while(cur != null){
                S.push(cur);
                preOrderArr.add(cur.getValue());
                cur = cur.getLeftChild();
            }
            cur = S.pop();
            cur = cur.getRightChild();
        }
    }

    private ArrayList<T> inOrderArr;

    // 中序遍历
    public ArrayList<T> inOrderRecur(BSTNode<T> cur){
        inOrderArr.clear();
        this.inOrderRecurImpl(cur);
        return inOrderArr;
    }

    public ArrayList<T> inOrderIter(BSTNode<T> cur){
        inOrderArr.clear();
        this.inOrderIterImpl(cur);
        return inOrderArr;
    }


    private void inOrderRecurImpl(BSTNode<T> cur){
        if(cur == null) return;
        inOrderRecurImpl(cur.getLeftChild());
        inOrderArr.add(cur.getValue());
        inOrderRecurImpl(cur.getRightChild());
    }

    private void inOrderIterImpl(BSTNode<T> cur){
        if(cur == null) return;
        Stack<BSTNode<T>> S = new Stack<BSTNode<T>>();
        while(!S.empty() || cur != null){
            while(cur != null){
                S.push(cur);
                cur = cur.getLeftChild();
            }
            cur = S.pop();
            inOrderArr.add(cur.getValue());
            cur = cur.getRightChild();
        }
    }

    private ArrayList<T> posOrderArr;

    // 后序遍历
    public ArrayList<T> posOrderRecur(BSTNode<T> cur){
        posOrderArr.clear();
        this.posOrderRecurImpl(cur);
        return posOrderArr;
    }

    public ArrayList<T> posOrderIter(BSTNode<T> cur){
        posOrderArr.clear();
        this.posOrderIterImpl(cur);
        return posOrderArr;
    }

    private void posOrderRecurImpl(BSTNode<T> cur){
        if(cur == null) return;
        posOrderRecurImpl(cur.getLeftChild());
        posOrderRecurImpl(cur.getRightChild());
        posOrderArr.add(cur.getValue());
    }

    private void posOrderIterImpl(BSTNode<T> cur){
        if(cur == null) return;
        Stack<BSTNode<T>> S = new Stack<BSTNode<T>>();
        while(!S.empty() || cur != null){
            while(cur != null){
                S.push(cur);
                posOrderArr.add(cur.getValue());
                cur = cur.getRightChild();
            }
            cur = S.pop();
            cur = cur.getLeftChild();
        }
        Collections.reverse(posOrderArr);
    }


    private ArrayList<T> levelOrderArr;

    // 层序遍历
    public ArrayList<T> levelOrder(BSTNode<T> cur){
        Queue<BSTNode<T>> Q = new LinkedList<BSTNode<T>>();
        Q.offer(cur);
        while(!Q.isEmpty()){
            cur = Q.poll();
            levelOrderArr.add(cur.getValue());
            if(cur.getLeftChild() != null)  Q.offer(cur.getLeftChild());
            if(cur.getRightChild() != null) Q.offer(cur.getRightChild());
        }
        return levelOrderArr;
    }

    // 求前驱和后继
}

有误指出。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值