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


    背景

    通过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结构似乎不能满足,于是想到了二叉树,基本逻辑是用二分法将数据排序,取中间的为根节点,向左向右取中间节点为左右子节点构建大树,然后按照二叉树逻辑检索,测试了一下性能还可以,记录一下。

    1. package org.example.util;
    2. import java.util.ArrayList;
    3. import java.util.Date;
    4. import java.util.List;
    5. import java.util.Random;
    6. public class CacheRange {
    7. public static void main(String[] args) {
    8. Date begin = new Date();
    9. long max = 4294967296l;
    10. long min =0;
    11. Random random = new Random();
    12. List nodes = new ArrayList<>();
    13. while(min < max){
    14. int increment = random.nextInt(1000);
    15. Node node = new Node(min,min+increment);
    16. nodes.add(node);
    17. min = min+increment;
    18. }
    19. Date now = new Date();
    20. System.out.println(nodes.size()+" cost "+(now.getTime()-begin.getTime()));
    21. int maxSize = nodes.size()-1;
    22. int minSize = 0;
    23. int curSize = (maxSize-minSize)/2;
    24. Node root = nodes.get(curSize);
    25. root.setLeft(getMidNode(nodes,curSize,minSize,true));
    26. root.setRight(getMidNode(nodes,maxSize,curSize,false));
    27. System.out.println(root);
    28. now = new Date();
    29. System.out.println("setMidNode cost "+(now.getTime()-begin.getTime()));
    30. long idx = 29496729l;
    31. for(int i=0;i<100;i++){
    32. Node node = root.indexNode(idx);
    33. System.out.println(idx+"@node is "+node);
    34. idx = idx + random.nextInt(1000);
    35. }
    36. now = new Date();
    37. System.out.println(nodes.size()+" cost "+(now.getTime()-begin.getTime()));
    38. }
    39. public static Node getMidNode(List nodes, int maxSize, int minSize,boolean isleft){
    40. int curSize = (maxSize-minSize)/2+minSize;
    41. Node root;
    42. if(maxSize-minSize <= 1){//这里考虑2个元素、1个元素情况
    43. if(isleft){
    44. root = nodes.get(minSize);
    45. }else{
    46. root = nodes.get(maxSize);
    47. }
    48. if(root.isExist){
    49. return null;
    50. }
    51. return root;
    52. }else{
    53. root = nodes.get(curSize);
    54. if(null == root || root.isExist){
    55. return null;
    56. }
    57. root.setLeft(getMidNode(nodes,curSize,minSize,true));
    58. root.setRight(getMidNode(nodes,maxSize,curSize,false));
    59. return root;
    60. }
    61. }
    62. static class Node{
    63. long begin = 0;
    64. long end = 0;
    65. Node left;
    66. Node right;
    67. boolean isExist =false;
    68. public Node(long begin,long end){
    69. this.begin=begin;
    70. this.end = end;
    71. }
    72. public void setLeft(Node left){
    73. this.left=left;
    74. }
    75. public Node getLeft(){
    76. return this.left;
    77. }
    78. public void setRight(Node right){
    79. this.right=right;
    80. }
    81. public Node getRight(){
    82. return this.right;
    83. }
    84. public void setIsExist(){
    85. this.isExist = true;
    86. }
    87. public Node indexNode(long index){
    88. if(this.begin <= index && this.end >= index){
    89. return this;
    90. }
    91. if(this.begin > index){
    92. return this.left.indexNode(index);
    93. }
    94. if(this.end < index){
    95. return this.right.indexNode(index);
    96. }
    97. return null;
    98. }
    99. @Override
    100. public String toString(){
    101. return this.begin+" - "+this.end;
    102. }
    103. }
    104. }

    测试的结果如下:

    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

    树结构

  • 相关阅读:
    互联网产品说明书指南,附撰写流程与方法
    万字长文:从实践到原理说透Golang defer
    axios.defaults.baseURL的三种配置方法
    Sublime Text:代码编辑器的卓越典范
    vs如何读取mysql中的数据(顺便通过代码解决了中文乱码问题)
    PXE操作过程 kickstart 无人值守安装
    虾皮shopee官方平台开放api接口采集商品数据信息获取产品详情数据根据关键词推荐获取商品列表、优惠价、销量调试示例
    1.Python是什么?——跟老吕学Python编程
    深度学习之PyTorch实战(4)——迁移学习
    发现Kafka bug
  • 原文地址:https://blog.csdn.net/u013456765/article/details/133660032