二叉树实现快速查找数字所在区间

news2025/1/12 0:56:13

背景

通过IP地址查询ip地址所属省市,存在这样的数据

3748137472,3748137727,223.104.10.0,223.104.10.255,中国,江西,,,移动,330000,,城域网
3748137728,3748137983,223.104.11.0,223.104.11.255,中国,陕西,,,移动,710000,,移动网络
3748137984,3748138239,223.104.12.0,223.104.12.255,中国,云南,,,移动,650000,,移动网络
3748138240,3748138495,223.104.13.0,223.104.13.255,中国,河北,,,移动,050000,,移动网络
3748138496,3748138751,223.104.14.0,223.104.14.255,中国,山西,,,移动,030000,,移动网络
3748138752,3748138815,223.104.15.0,223.104.15.63,中国,内蒙古,,,移动,010000,,移动网络
3748138816,3748138847,223.104.15.64,223.104.15.95,中国,内蒙古,,,移动,020000,,移动网络

通过将IP地址翻译成数字比较数字所属区间找到对应的省市信息,单个或多个查询都没问题,如果批量查询上万个,对oracle的性能是很大的考验,于是想到了缓存,但是普通的map结构似乎不能满足,于是想到了二叉树,基本逻辑是用二分法将数据排序,取中间的为根节点,向左向右取中间节点为左右子节点构建大树,然后按照二叉树逻辑检索,测试了一下性能还可以,记录一下。

package org.example.util;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

public class CacheRange {

    public static void main(String[] args) {
        Date begin = new Date();
        long max = 4294967296l;
        long min =0;
        Random random = new Random();
        List<Node> nodes = new ArrayList<>();

        while(min < max){
            int increment = random.nextInt(1000);

            Node node = new Node(min,min+increment);
            nodes.add(node);
            min = min+increment;
        }
        Date now = new Date();
        System.out.println(nodes.size()+" cost "+(now.getTime()-begin.getTime()));
        int maxSize = nodes.size()-1;
        int minSize = 0;
        int curSize = (maxSize-minSize)/2;
        Node root = nodes.get(curSize);
        root.setLeft(getMidNode(nodes,curSize,minSize,true));
        root.setRight(getMidNode(nodes,maxSize,curSize,false));

        System.out.println(root);
        now = new Date();
        System.out.println("setMidNode cost "+(now.getTime()-begin.getTime()));

        long idx = 29496729l;
        for(int i=0;i<100;i++){
            Node node = root.indexNode(idx);
            System.out.println(idx+"@node is "+node);
            idx = idx + random.nextInt(1000);
        }
        now = new Date();
        System.out.println(nodes.size()+" cost "+(now.getTime()-begin.getTime()));
    }

    public static Node getMidNode(List<Node> nodes, int maxSize, int minSize,boolean isleft){
        int curSize = (maxSize-minSize)/2+minSize;
        Node root;
        if(maxSize-minSize <= 1){//这里考虑2个元素、1个元素情况
            if(isleft){
                root = nodes.get(minSize);
            }else{
                root = nodes.get(maxSize);
            }
            if(root.isExist){
                return null;
            }
            return root;
        }else{
            root = nodes.get(curSize);
            if(null == root || root.isExist){
                return null;
            }
            root.setLeft(getMidNode(nodes,curSize,minSize,true));
            root.setRight(getMidNode(nodes,maxSize,curSize,false));
            return root;
        }
    }

    static class Node{
        long begin = 0;
        long end = 0;
        Node left;
        Node right;
        boolean isExist =false;
        public Node(long begin,long end){
            this.begin=begin;
            this.end = end;
        }

        public void setLeft(Node left){
            this.left=left;
        }
        public Node getLeft(){
            return this.left;
        }
        public void setRight(Node right){
            this.right=right;
        }
        public Node getRight(){
            return this.right;
        }

        public void setIsExist(){
            this.isExist = true;
        }

        public Node indexNode(long index){
            if(this.begin <= index && this.end >= index){
                return this;
            }
            if(this.begin > index){
                return this.left.indexNode(index);
            }
            if(this.end < index){
                return this.right.indexNode(index);
            }

            return null;
        }

        @Override
        public String toString(){
            return this.begin+" - "+this.end;
        }
    }
}

测试的结果如下:

8597917 cost 2347
2146951032 - 2146951635
setMidNode cost 2461
29496729@node is 29496411 - 29497393
29497062@node is 29496411 - 29497393
29497953@node is 29497466 - 29498096

......
29544412@node is 29544398 - 29544647
29545207@node is 29544647 - 29545591
8597917 cost 2462

Process finished with exit code 0

树结构

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1067780.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1.7 计算机网络体系结构

思维导图&#xff1a; 1.7.1 计算机网络的体系结构的形成 **1.7 计算机网络体系结构** 计算机网络体系结构中&#xff0c;分层的思想为核心。该方法使得复杂的网络设计变得更为简单和可管理。 **1.7.1 计算机网络体系结构的形成** - **计算机网络的复杂性**: 即使是简单的文…

2.4 信道复用技术

前言&#xff1a; 2.4.1 频分复用、时分复用和统计时分复用 **2.4 信道复用技术笔记** --- **1. 定义&#xff1a;** - **复用 (Multiplexing)**&#xff1a;允许多个用户共享一个传输介质&#xff0c;从而提高资源使用效率。 --- **2. 基本复用示意&#xff1a;** - 使用…

SQL进阶 - SQL的编程规范

性能优化是一个很有趣的探索方向&#xff0c;将耗时耗资源的查询优化下来也是一件很有成就感的事情&#xff0c;但既然编程是一种沟通手段&#xff0c;那每一个数据开发者就都有义务保证写出的代码逻辑清晰&#xff0c;具有很好的可读性。 目录 引子 小试牛刀 答案 引言 …

互联网图片安全风控实战训练营开营!

内容安全风控&#xff0c;即针对互联网产生的海量内容的外部、内部风险做宏观到微观的引导和审核&#xff0c;从内容安全领域帮助企业化解监管风险和社会舆论风险&#xff0c;其核心是识别文本、图片、视频、音频中的有害内容。 由于互联网内容类型繁杂、多如牛毛&#xff0c;加…

mysql面试题22:SQL优化的一般步骤是什么,怎么看执行计划(explain),如何理解其中各个字段的含义

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:SQL优化的一般步骤是什么,怎么看执行计划(explain),如何理解其中各个字段的含义 SQL优化的一般步骤如下: 分析和理解问题:首先,要确保对问…

Mysql 8手动终止某个事务并释放其持有的锁

示范数据表 age具有index普通索引 在mysql数据库里的information_schema.INNODB_TRX表中存储有innodb的所有事务&#xff0c;我们可以查看该表来查看正在进行的事务 现在我开启一个事务&#xff0c;执行第1、2行SQL&#xff0c;启动事务并持有id3的行锁 刷新事务表可以看到…

JavaScript 笔记 初识JavaScript(变量)

1 打开js文件方法 1.1 方法1&#xff1a;用html打开 第⼀步&#xff1a;把JS程序存储为⼀个扩展名为js的⽂本⽂件 第⼆步&#xff1a;把js⽂件关联到⼀个HTML⽂件上 <!DOCTYPE html> <html><body><script src1.js></script><body> </…

【微服务】七. http客户端Feign

7.1 基于Feign远程调用 RestTimeplate方式调用存在的问题 先来看以前利用RestTemplate发起远程调用的代码&#xff1a; String url "http://userservice/user"order.getUserId(); User user restTemplate.getForObject(url,User.class);存在下面的问题&#xf…

数据产品读书笔记——认识数据产品经理

&#x1f33b;大家可能听说的更多是产品经理这个角色&#xff0c;对数据产品经理可能或多或少了解一些&#xff0c;但又不能准确的描述数据产品经理的主要职能和与其他产品的不同&#xff0c;因此通过读一些书来对数据产品经理有一个准确且全面的认知。 目录 1. 数据的产品分类…

STC89C51基础及项目第10天:LCD显示字符(非标协议外设)

1. 初识LCD1602&#xff08;233.79&#xff09; 非标协议外设 LCD1602显示 LCD1602&#xff08;Liquid Crystal Display&#xff09;是一种工业字符型液晶&#xff0c;能够同时显示 1602 即 32 字符(16列两行) 引脚说明 第 1 脚&#xff1a; VSS 为电源地第 2 脚&#xff1…

vue3前端开发-flex布局篇

文章目录 1.传统布局与flex布局优缺点传统布局flex布局建议 2. flex布局原理2.1 布局原理 3. flex常见属性3.1 父项常见属性3.2 子项常见属性 4.案例实战(携程网首页) 1.传统布局与flex布局优缺点 传统布局 兼容性好布局繁琐局限性&#xff0c;不能再移动端很好的布局 flex布…

【C++入门到精通】C++入门 —— 红黑树(自平衡二叉搜索树)

阅读导航 前言一、红黑树的概念二、红黑树的性质三、红黑树节点的定义四、红黑树结构&#xff08;带有头结点的红黑树&#xff09;五、红黑树的插入操作1. 按照二叉搜索的树规则插入新节点2. 新节点插入后&#xff0c;红黑树的变色以及旋转情况1&#xff1a; cur为红&#xff0…

nginx-proxy反向代理缓存

介绍&#xff1a; 反向代理缓存&#xff0c;类似于动静分离&#xff0c;即通过nginx代理服务器根据客户端发送的url请求&#xff0c;去后台服务器获取数据&#xff0c;将静态数据缓存到nginx代理服务器上&#xff0c;并配置有过期时间&#xff0c;当客户端下次以相同的url请求…

【机器学习】决策树原理及scikit-learn使用

文章目录 决策树详解ID3 算法C4.5算法CART 算法 scikit-learn使用分类树剪枝参数重要属性和接口 回归树重要参数&#xff0c;属性及接口交叉验证代码示例 一维回归的图像绘制 决策树详解 决策树&#xff08;Decision Tree&#xff09;是一种非参数的有监督学习方法&#xff0c;…

blender 之视频渲染(以三维重建path为例)

blender 之视频渲染&#xff08;以三维重建path为例&#xff09; 1.新建轨迹路径2.设置相机&#xff0c;使其按照path运动3.将相机视角对准物体4.修改帧率5.设置输出路径6.设置输出格式7.渲染 1.新建轨迹路径 新建轨迹 选中新建的BezierCycle&#xff0c;按住S&#xff0c;拖…

基于支持向量机SVM和MLP多层感知神经网络的数据预测matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 一、支持向量机&#xff08;SVM&#xff09; 二、多层感知器&#xff08;MLP&#xff09; 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 .…

mysql面试题23:如果某个表有近千万数据,CRUD比较慢,如何优化?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:如果某个表有近千万数据,CRUD比较慢,如何优化? 当某个表存在近千万数据且CRUD(增删改查)操作比较慢时,可以考虑以下优化策略: 使用索引:索…

3.1.OpenCV技能树--二值图像处理--图像腐蚀与膨胀

文章目录 1.文章内容来源2.图像膨胀处理2.1.图像膨胀原理简介2.2.图像膨胀核心代码2.3.图像膨胀效果展示 3.图像腐蚀处理3.1.图像腐蚀原理简介3.2.图像腐蚀核心代码3.3.图像腐蚀效果展示 4.易错点总结与反思 1.文章内容来源 1.题目来源:https://edu.csdn.net/skill/practice/o…

LVS+Keepalived 高可用集群负载均衡

一.keepalived介绍 1.1.Keepalived实现原理 由多台路由器组成一个热备组&#xff0c;通过共用的虚拟IP地址对外提供服务。 每个热备组内同时只有一台主路由器提供服务&#xff0c;其他路由器处于冗余状态。 若当前在线的路由器失效&#xff0c;则其他路由器会根据设置…

(论文调研) Multi-task的网络结构 在图像去噪问题中的应用

1.SNIDER: Single Noisy Image Denoising and Rectification for Improving License Plate Recognition 这是一篇用于实现端到端的车牌恢复 (LPR: License Plate Recognition) 网络, 其中使用去噪和校正网络来生成清晰的恢复图像, 以实现稳健的 LPR 性能. 这个网络的名称为SN…