数据结构之二叉搜索树

java实现二叉搜索树

public class AVLTree {

    private AVLTreeNode header;
    private boolean flag = true;

    public void insert(int element) {
        header = insert(header, element);
    }

    private int getHeight(AVLTreeNode node) {
        if (node == null) {
            return 0;
        } else {
            return node.height;
        }
    }

    private AVLTreeNode insert(AVLTreeNode node, int element) {
        // 和二叉搜索树插入相似,多了一个配需的过程
        if (node == null) { // 表示需要建立新的节点
            node = new AVLTreeNode(null, null, element, 0);
        } else if (element < node.data) { // 需要进行左子树插入
            node.lchild = insert(node.lchild, element);
            // 需要进行判断是否平衡,====判断左子树
            if (getHeight(node.lchild) - getHeight(node.rchild) == 2) { // 需要进行左旋
                if (element < node.lchild.data) {
                    node = singleLeftRotation(node); // LL型,称为右单旋
                } else { // LR型,先左旋在右旋
                    node = doubleLeftRightRotation(node);
                }
            }
        } else if (element > node.data) {
            node.rchild = insert(node.rchild, element);
            if (getHeight(node.lchild) - getHeight(node.rchild) == -2) {
                if (element > node.rchild.data) { // RR型,左单旋
                    node = singleRightRotation(node);
                } else { // RL型,先右旋,在左旋
                    node = doubleRightLeftRotation(node);
                }
            }
        }
        node.height = Math.max(getHeight(node.lchild), getHeight(node.rchild)) + 1;
        return node;
    }

    // LL型,称为右单旋====右旋
    private AVLTreeNode singleLeftRotation(AVLTreeNode node) {
        // 节点:node一定要有左孩子节点
        AVLTreeNode tmp = node.lchild;
        node.lchild = tmp.rchild;
        tmp.rchild = node;
        // 更新高度
        node.height = Math.max(getHeight(node.lchild), getHeight(node.rchild)) + 1;
        tmp.height = Math.max(getHeight(tmp.lchild), node.height) + 1;
        // 返回新的根节点
        return tmp;
    }

    // LR型,先左旋在右旋
    private AVLTreeNode doubleLeftRightRotation(AVLTreeNode node) {
        // 前提:节点node需要有左孩子和右孩子,做两次旋转
        // 将LR型 转化为----》
        node.lchild = singleRightRotation(node.lchild); // RR型---左旋
        return singleLeftRotation(node); // LL型 ----右旋
    }

    // RR型,左单旋
    private AVLTreeNode singleRightRotation(AVLTreeNode node) {
        // 节点:node一定要有右孩子节点
        AVLTreeNode tmp = node.rchild;
        if (tmp != null) {
            node.rchild = tmp.lchild;
            tmp.lchild = node;
            // 更新高度
            node.height = Math.max(getHeight(node.lchild),
                    getHeight(node.rchild)) + 1;
            tmp.height = Math.max(node.height, getHeight(tmp.rchild)) + 1;
        }
        // 返回新的根节点
        return tmp;
    }

    // RL型,先右旋,在左旋
    private AVLTreeNode doubleRightLeftRotation(AVLTreeNode node) {
        // 前提:节点node需要有左孩子和右孩子,做两次旋转
        // 将RL型 转化为----》 先右旋在左旋
        node.rchild = singleLeftRotation(node.rchild); // LL型---右旋
        return singleRightRotation(node); // RR型 ----左旋
    }

    // 进行层次遍历
    public void levelOrder() {
        levelOrder(header);
    }

    // 进行层次遍历,利用队列进行
    private void levelOrder(AVLTreeNode node) {

        AVLTreeNode[] nodes = new AVLTreeNode[100];
        AVLTreeNode tmp = null;
        int rear = 0;
        int front = 0;
        if (node != null) {
            rear++;
            nodes[rear] = node;
            while (rear != front) { // 判断队列是否为空
                // 取元素
                front = (front + 1) % 100;
                tmp = nodes[front];
                System.out.print(tmp.data); // 打印节点
                if(rear != front ||  flag){
                    flag = false;
                    System.out.print(",");
                }
                if (tmp.lchild != null) {
                    // 进入队列
                    rear = (rear + 1) % 100;
                    nodes[rear] = tmp.lchild;
                }
                if (tmp.rchild != null) {
                    // 进入队列
                    rear = (rear + 1) % 100;
                    nodes[rear] = tmp.rchild;
                }
            }
            System.out.println();
        }
    }

    /**
     * 获得数的高度
     * @return
     */
    public int getTreeHeight(){
        return getHeight(header);
    }

    /**
     * 查找指定元素的节点
     * @param element
     * @return
     */
    public AVLTreeNode find(int element){
        return find(header, element);
    }
    /**
     * 查找节点
     * @param node
     * @param element
     * @return
     */
    public AVLTreeNode find(AVLTreeNode node, int element) {
        if (node == null) {
            System.out.println("element id not find in AVLTree");
        }else if (element < node.data) {
            return find(node.lchild, element);
        } else if (element > node.data) {
            return find(node.rchild, element);
        }
       return node;
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值