IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> AVLTree-insert() -java -> 正文阅读

[数据结构与算法]AVLTree-insert() -java

java avlTree insert()

package avltree;

public class AVLTree {
    static class AVLTreeNode{
        public int value = 0; // 节点的内容 ;
        public int balance_factor = 0; // 当前节点的平衡因子;
        public AVLTreeNode left = null; // 左孩子
        public AVLTreeNode right = null; // 右边孩子
        public AVLTreeNode parent = null; // 节点的双亲

        public AVLTreeNode(int value) {
            this.value = value;
        }
    }
    public AVLTreeNode root = null;
    // 平衡二叉树的插入
    // 1. 按照二叉搜索数的方式 插入新的节点;

    public boolean insert(int val) throws Exception {
        // 先按照 二叉搜索树的 规则 将节点插入 ;
        if(root == null){
            root = new AVLTreeNode(val);
            return true;
        }
        AVLTreeNode parent = null;
        AVLTreeNode cur = root;
        while(cur != null){
            if(cur.value < val){
                parent = cur;
                cur = cur.right;
            }else if(cur.value > val){
                parent = cur;
                cur = cur.left;
            }else {// cur.value == val;
                return false; // treeSet TreeMap 的 key 不可以重复;
            }
        }
        // 当 cur == null 退出循环 此时找到要插入的位置;
        cur = new AVLTreeNode(val);
        if(parent.value < val){
            parent.right = cur;
        }else {
            parent.left = cur;
        }
        // 新增插入完成 ;
        cur.parent = parent;
        // 2. 调整节点的平衡因子;
        // 2.1 从当前位置向上 调节parent 的 balance_factor ;
        // 2.2 根据 parent.balance_factor 采取对应的平衡策略;
        while(parent != null){
            if(cur == parent.left){
                parent.balance_factor--;
            }else {
                parent.balance_factor++;
            }
            if(parent.balance_factor == 0){
                break; // 当前增量相对与上层没有变化,不用继续向上 ;
            }else if(parent.balance_factor == 1 || parent.balance_factor == -1){
                // 增量对上层会造成影响;
                cur = parent;
                parent = parent.parent;
            }else if(parent.balance_factor == 2){// 需要进行调整 (右子树增量 破防);
                    if(cur.balance_factor == 1){ // 这里证明 是右子树的右子树 增量导致
                        // 需要进行左单旋转;
                        RotateL(parent);
                    }else { // cur.balance_factor == -1;
                        // parent 的右子树的左子树 发生增量 需要给 parent.right 先做一个右单旋,再给parent 来个左单旋转;
                        // 简称 右左 双旋转;
                        RotateRL(parent);
                    }
                    // 调整结束就不用再向上调整,下层能够摆平就不劳烦上层
                    break;
            }else if(parent.balance_factor == -2){// 需要进行调整 (左子树增量 破防) ;
                    if(cur.balance_factor == -1){ // 这里证明 是parent 的左子树的左子树上的增量导致的;
                        // 需要来个右单旋
                        RotateR(parent);
                    }else{ // cur.balance_factor == 1;
                        // parent 的左子树的右子树的增量
                        // 需要对 parent 左子树进行左单旋,再对 parent 进行右单旋;
                        RotateLR(parent);
                    }
                break;
            }else {
                throw new Exception("balance_factor 异常 ");
            }
        } // 平衡因子调节完成 , 插入完毕;
        return true;
    }


    // 原因 : 需要右左双旋,是因为 parent 的右子树的左子树 产生了增量导致
    private void RotateRL(AVLTreeNode parent) {
        AVLTreeNode cur = parent.right;
        AVLTreeNode curL = cur.left;
        // 根据右子树的左子树 的增量平衡因子确定 平衡后 parent , cur 和 curL 的 balance_factor;
        int balance_factor = curL.balance_factor;
        RotateR(cur);
        RotateL(parent);

        if(balance_factor == -1){
            parent.balance_factor = 0;
            cur.balance_factor = 1;
            curL.balance_factor = 0;
        }else if(balance_factor == 1){
            parent.balance_factor = -1;
            cur.balance_factor = 0;
            curL.balance_factor = 0;
        }else { // balance_factor == 0;
            parent.balance_factor = 0;
            cur.balance_factor = 0;
            curL.balance_factor = 0;
        }
    }

    // 增量产生与 parent 的左子树的右子树上,具体调节依赖curR.balance_factor 的值
    private void RotateLR(AVLTreeNode parent) {
        AVLTreeNode cur = parent.left;
        AVLTreeNode curR = cur.right;
        int balance_factor = curR.balance_factor;

        RotateL(cur);
        RotateR(parent);

        if(balance_factor == -1){
            cur.balance_factor = 0;
            parent.balance_factor = 1;
            curR.balance_factor = 0;
        }else if(balance_factor == 1){
            parent.balance_factor = 0;
            cur.balance_factor = -1;
            curR.balance_factor = 0;
        }else {
            parent.balance_factor = 0;
            cur.balance_factor = 0;
            curR.balance_factor = 0;
        }
    }

    // 左单旋;
    private void RotateL(AVLTreeNode parent) {
        AVLTreeNode cur = parent.right;
        AVLTreeNode curL = cur.left;
        parent.right = curL;
        if(parent.parent != null){
            if(parent == parent.parent.left){
                parent.parent.left = cur;
            }else {
                parent.parent.right = cur;
            }
            cur.parent = parent.parent;
        }else {
            root = cur;
            root.parent = null;
        }
        parent.parent = cur;
        cur.left = parent;
        if(curL != null){
            curL.parent = parent;
        }

        parent.balance_factor = 0;
        cur.balance_factor = 0;
    }
    // 右单旋;
    private void RotateR(AVLTreeNode parent) {
        AVLTreeNode cur = parent.left;
        AVLTreeNode curR = cur.right;

        parent.left = curR;

        if(parent.parent != null){
            if(parent == parent.parent.left){
                parent.parent.left = cur;
            }else {
                parent.parent.right = cur;
            }
            cur.parent = parent.parent;
        }else {
            root = cur;
            root.parent = null;
        }
        parent.parent = cur;
        cur.right = parent;
        if(curR != null){
            curR.parent = parent;
        }
        parent.balance_factor = 0;
        cur.balance_factor = 0;
    }

    void midOrder(AVLTreeNode root){
        if(root == null) return ;
        midOrder(root.left);
        System.out.print(root.value+" ");
        midOrder(root.right);
    }

    public static void main(String[] args) throws Exception {
        AVLTree avlTree = new AVLTree();
        int[] arr = {3,6,8,9,23,7,6,90};
        for(int num : arr){
            avlTree.insert(num);
        }
        avlTree.midOrder(avlTree.root);
    }
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-12-26 22:27:24  更:2021-12-26 22:28:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 17:51:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码