宿迁腾云网络网站建设公司

腾云网络 八年经验专注网站建设
  • 首页
  • 服务项目
    • 网站建设
    • 微信小程序
    • APP开发
    • SEO优化
  • 建站费用
  • 成功案例
    • 网站建设案例
    • 小程序案例
    • APP开发案例
    • SEO优化案例
  • 行业动态
    • 网站建设
    • SEO优化
    • 技术日志
  • 联系我们
    • 关于我们
首页 > 行业动态 > 技术日志 > php开发手册线段树是为区间更新和区间查询而生的数据结构,旨在快速解决区间问题力软开发框架的开发手册

php开发手册线段树是为区间更新和区间查询而生的数据结构,旨在快速解决区间问题力软开发框架的开发手册

2022-03-25

线段树是一种用于区间更新和区间查询的数据结构,旨在快速解决区间问题。

一般来说,线段树不会添加节点,也不支持动态添加节点。段树也是二叉树的一种,但它的节点是由一个区间定义的。叶节点是具有单个间隔的节点。所以线段树本质上是一棵区间树。

我们在搜索的时候,只需要找出哪些子区间构成了结果区间。

实现代码

先定义基本结构

public class SegmentTree {
    
    private Integer value;
    private Integer maxValue;
    private Integer l;
    private Integer r;
    
    private SegmentTree leftChild;
    private SegmentTree rightChild;
}
复制代码

l 和 r 用于唯一地表征这个区间。那么其他的内容就和标准的二叉树没什么区别了。

​​​

建树过程

和二叉树构造没什么区别,我们这里使用的是前序构造方法。代码显示如下:

public static SegmentTree buildTree(int left, int right, int[] value) {
    if (left > right) {
        return null;
    }
    SegmentTree node = new SegmentTree();
    node.setValue(value[left]);
    node.setL(left);
    node.setR(right);
    if (left == right) {
        // TODO: 2022/1/17 退出条件
        node.setMaxValue(node.getValue());
        return node;
    }
    int mid = (left + right) >>> 1;
    node.setLeftChild(buildTree(left, mid, value));
    node.setRightChild(buildTree(mid + 1, right, value));
    if (Objects.isNull(node.getLeftChild())) {
        if (Objects.isNull(node.getRightChild())) {
            node.setMaxValue(node.getValue());
        } else {
            node.setMaxValue(node.getRightChild().getMaxValue());
        }
    } else {
        if (Objects.isNull(node.getRightChild())) {
            node.setMaxValue(node.getLeftChild().getMaxValue());
        } else {
            node.setMaxValue(Math.max(node.getLeftChild().getMaxValue(),
                                      node.getRightChild().getMaxValue()));
        }
    }
    return node;
}
复制代码

可以看出,这里叶子节点的判断条件是 left == 。在其他方面,它与二叉树没有什么不同。

​​​

查询区间最大值

public static Integer getMaxValue(SegmentTree segmentTree, int left, int right) {
    if (Objects.isNull(segmentTree)) return null;
    if (segmentTree.getL() == left && segmentTree.getR() == right) {
        System.out.println("获取了区间 [" + left + "," + right + "] 的最大值" + segmentTree.getMaxValue());
        return segmentTree.getMaxValue();
    }
    int segMid = (segmentTree.getL() + segmentTree.getR()) >>> 1;
    if (segMid < left) {
        return getMaxValue(segmentTree.getRightChild(), left, right);
    }
    if (segMid >= right) {
        return getMaxValue(segmentTree.getLeftChild(), left, right);
    }
    // TODO: 2022/1/17 左半边答案
    Integer leftMax = getMaxValue(segmentTree.getLeftChild(), left, segMid);
    Integer rightMax = getMaxValue(segmentTree.getRightChild(), segMid + 1, right);
    if (Objects.isNull(leftMax)) {
        if (Objects.isNull(rightMax)) {
            return -100000;
        } else {
            return rightMax;
        }
    } else {
        if (Objects.isNull(rightMax)) {
            return leftMax;
        } else {
            return Math.max(leftMax, rightMax);
        }
    }
}
复制代码

从上面的代码分析,设置当前节点的区间为[L,R],那么对于区间[l,r]的最大值,需要进行分类讨论。如果LR区间的中点Mid在lr区间的左侧,则max(lr) = max( , l, r); 如果LR区间的中点在lr区间的右侧,则max(lr) = max(left , l, r); 如果 Mid 在 lr 区间内,max(lr) = max(left , l, mid) 和 max( , mid+1, r) 中的较大者。

​​​

我们来看看测试用例和运行结果:

public static void main(String[] args) {
    int[] a = new int[]{2, 5, 4, 7, 6, 0, 1, -1, 2, 3, 6, 7, 0, 2, 9, 8, 5, 4, 7, 2};
    SegmentTree segmentTree = buildTree(0, a.length - 1, a);
    System.out.println(getMaxValue(segmentTree, 0, 16));
}
复制代码

结果如下

得到区间[0,9]的最大值 7 得到区间[10,14]的最大值 得到区间[15,16]的最大值 8 9

得到间隔和

现在需要改变原来的建树过程。首先php开发手册,将 sum 字段添加到基础架构

public class SegmentTree {
    private Integer value;
    private Integer maxValue;
    private Integer sum;
    private Integer l;
    private Integer r;
    private SegmentTree leftChild;
    private SegmentTree rightChild;
}
复制代码

然后在构造方法中,加上sum的维护

public static SegmentTree buildTree(int left, int right, int[] value) {
    if (left > right) {
        return null;
    }
    SegmentTree node = new SegmentTree();
    node.setValue(value[left]);
    node.setL(left);
    node.setR(right);
    if (left == right) {
        // TODO: 2022/1/17 退出条件
        node.setMaxValue(node.getValue());
        node.setSum(node.getValue());
        return node;
    }
    int mid = (left + right) >>> 1;
    node.setLeftChild(buildTree(left, mid, value));
    node.setRightChild(buildTree(mid + 1, right, value));
    if (Objects.isNull(node.getLeftChild())) {
        if (Objects.isNull(node.getRightChild())) {
            node.setMaxValue(node.getValue());
            node.setSum(node.getValue());
        } else {
            node.setMaxValue(node.getRightChild().getMaxValue());
            node.setSum(node.getRightChild().getSum());
        }
    } else {
        if (Objects.isNull(node.getRightChild())) {
            node.setMaxValue(node.getLeftChild().getMaxValue());
            node.setSum(node.getLeftChild().getSum());
        } else {
            node.setMaxValue(Math.max(node.getLeftChild().getMaxValue(),
                                      node.getRightChild().getMaxValue()));
            node.setSum(node.getLeftChild().getSum() + node.getRightChild().getSum());
        }
    }
    return node;
}
复制代码

然后得到总和

public static Integer getSum(SegmentTree segmentTree, int left, int right) {
    if (Objects.isNull(segmentTree)) return null;
    if (segmentTree.getL() == left && segmentTree.getR() == right) {
        System.out.println("获取了区间 [" + left + "," + right + "] 的和" + segmentTree.getSum());
        return segmentTree.getSum();
    }
    int segMid = (segmentTree.getL() + segmentTree.getR()) >>> 1;
    if (segMid < left) {
        return getSum(segmentTree.getRightChild(), left, right);
    }
    if (segMid >= right) {
        return getSum(segmentTree.getLeftChild(), left, right);
    }
    // TODO: 2022/1/17 左半边答案
    Integer leftSum = getSum(segmentTree.getLeftChild(), left, segMid);
    Integer rightSum = getSum(segmentTree.getRightChild(), segMid + 1, right);
    if (Objects.isNull(leftSum)) {
        if (Objects.isNull(rightSum)) {
            return segmentTree.getSum();
        } else {
            return rightSum;
        }
    } else {
        if (Objects.isNull(rightSum)) {
            return leftSum;
        } else {
            return leftSum + rightSum;
        }
    }
}
复制代码

测试过程和结果如下:

public static void main(String[] args) {
    int[] a = new int[]{2, 5, 4, 7, 6, 0, 1, -1, 2, 3, 6, 7, 0, 2, 9, 8, 5, 4, 7, 2};
    SegmentTree segmentTree = buildTree(0, a.length - 1, a);
    System.out.println(getSum(segmentTree,0,3));
}
复制代码

得到区间[0,2]之和 11 得到区间[3,3]之和 7 18

单点更新

/**
     * 这里的left == right
     *
     * @param segmentTree
     * @param left
     * @param right
     * @param value
     */
public static void update(SegmentTree segmentTree, int left, int right, int value) {
    if (segmentTree.getL() == left && segmentTree.getR() == right) {
        segmentTree.setValue(value);
        segmentTree.setMaxValue(value);
        segmentTree.setSum(value);
        return;
    }
    int mid = (segmentTree.getL() + segmentTree.getR()) >>> 1;
    if (mid >= left) {
        update(segmentTree.getLeftChild(), left, right, value);
    }
    if (mid < left) {
        update(segmentTree.getRightChild(), left, right, value);
    }
    segmentTree.setMaxValue(Math.max(segmentTree.getLeftChild().getMaxValue(),segmentTree.getRightChild().getMaxValue()));
    segmentTree.setSum(segmentTree.getLeftChild().getSum() + segmentTree.getRightChild().getSum());
}
复制代码

更新时采用递归的方式从左右节点不断寻找需要更新的区间,同时更新上级节点的最新值。

总结

您可以根据需要扩展它。请记住小程序开发,线段树是以区间为维度的二叉树,或以二维维度为特征的二叉树。普通的二叉树只有一维。这样php开发手册,我们在计算多维值的时候网站优化,其实可以这样构造线段树(二维树、三维树、n维树)。不管树的维数多少,找到结束状态和子状态是关键中的关键。典型的方法是分类讨论。前期不要怕分太多,太细可以合并。

最后

如果你觉得这篇文章对你有一点帮助,请给它一个大拇指。或者你也可以加入我的开发交流群:互相学习,我们会有专业的技术答疑

如果你觉得这篇文章对你有用,请给我们的开源项目一个小星星:非常感谢!

PHP学习手册:

技术交流论坛:

Tag: 区间 节点 手册
网站制作公众号

宿迁腾云网络网站建设公司 | 网站开发 | 网站制作 | 网站优化

咨询电话:13160355545

上一篇

返回栏目

下一篇

免责声明:本站所有文章和图片均来自用户分享和网络收集,文章和图片版权归原作者及原出处所有,仅供学习与参考,请勿用于商业用途,如果损害了您的权利,请联系网站客服处理。

热推

  • 关于开发语言(是什么语言,主要应用在哪些开发?)
  • 微软内核工程师阿列克斯:用什么编程语言来写的呢?
  • php 源码编译 不加载扩展独立的PHP扩展可以独立于PHP源码之外进行分发?源码编译安装php
  • 2018年IEEE顶级编程语言交互排行榜和2017年排行榜对比图
  • 如何从一个简单的网站架构演进发展成大型网站
  • 电脑配件6.后端三、买家须知(2015.03.23)
  • 点“查看报表”可以查看网站的统计系统来使用
  • 怎么修改HTML标签属性下一篇:继承的6种方法是什么
  • php文件上传代码 【点击查看】黑客技术文档学习书籍全套工具包相关教学视频php 文件上传源码
  • IEEE发布第四届顶级编程语言交互排行榜(图)语言排行

相关

一致性hash算法php开源陆陆续续服务器模式存在一个问题:

如何使用实现评论、回复、点赞等各种功能?

如何使用实现评论、回复、点赞等各种功能?

PHP IDEs与PHP CLI工具:助力高效PHP开发,满

PHP IDEs与PHP CLI工具:助力高效PHP开发,满

什么是PHP?其优势有简单易学、安全性高、开发效率高及社区活

什么是PHP?其优势有简单易学、安全性高、开发效率高及社区活

深入学习PHP编程基础与高级技术,掌握数字时代开发技能

PHP中七个常用框架介绍,详细解读ThinkPHP及其他框架

Science Technology:PHP开发平台发展历程

Science Technology:PHP开发平台发展历程

如何修复被黑客篡改的网站代码与数据库?入侵迹象与范围评估指南

如何修复被黑客篡改的网站代码与数据库?入侵迹象与范围评估指南

了解常见PHP应用程序安全威胁,掌握6个常见安全性攻击

了解常见PHP应用程序安全威胁,掌握6个常见安全性攻击

微信支付SDK漏洞曝光!谁会用到它?商家必看

标签

seo(1182) 市场营销(661) 网站制作(573) 网站建设(564) 搜索引擎(553) 网站(482) PHP(361) 编程语言(345) 建站(294) 关键词排名优化(267) 网站建设公司(245) 优化(216) seo排名(207) 域名(190) 软件(171) 网站优化(148) 搜索引擎优化(146) 外链(141) 科技(136) 网站关键词(124) 网站排名优化(123) 域名服务器(120) 网站排名(107) 时政(103) 排名优化(95) 搜索引擎收录(93) 网站设计(92) 电子商务(88) 引擎(86) 移动互联网(85) 开发框架(79) 开发(75) 网站服务器(74) 框架(68) 前端开发(68) 网站分析(66) 网站建设方案(65) 关键(64) 流量(63) 源码(62) 百度优化(62) 网站权重(61) 开放源代码(59) seo培训(53) 网页设计(51) 百度(51) php框架(50) 网站建设知识(50) 大数据(50) 谷歌(49)
宿迁腾云网络网站建设公司
网站建设
  • 私人定制
  • 标准模板建站
  • 经济模板建站
精品模板

宿迁腾云网络网站建设公司

联系电话:13160355545

公司地址:江苏省宿迁市丽景湾华庭北门都市花园公寓9楼907

联系邮箱:admin@tyweb.net

全国分站
  • 北京
  • 广东
  • 东莞 广州 中山 深圳 惠州 江门 珠海 汕头 佛山 湛江 河源 肇庆 潮州 清远 韶关 揭阳 阳江 云浮 茂名 梅州 汕尾
  • 山东
  • 济南 青岛 临沂 济宁 菏泽 烟台 泰安 淄博 潍坊 日照 威海 滨州 东营 聊城 德州 莱芜 枣庄
  • 江苏
  • 苏州 徐州 盐城 无锡 南京 南通 连云港 常州 扬州 镇江 淮安 泰州 宿迁
  • 河南
  • 郑州 南阳 新乡 安阳 洛阳 信阳 平顶山 周口 商丘 开封 焦作 驻马店 濮阳 三门峡 漯河 许昌 鹤壁 济源
  • 上海
  • 河北
  • 石家庄 唐山 保定 邯郸 邢台 沧州 秦皇岛 张家口 衡水 廊坊 承德
  • 浙江
  • 温州 宁波 杭州 台州 嘉兴 金华 湖州 绍兴 舟山 丽水 衢州
  • 陕西
  • 西安 咸阳 宝鸡 汉中 渭南 安康 榆林 商洛 延安 铜川
  • 湖南
  • 长沙 邵阳 常德 衡阳 株洲 湘潭 永州 岳阳 怀化 郴州 娄底 益阳 张家界 湘西
  • 重庆
  • 福建
  • 漳州 泉州 厦门 福州 莆田 宁德 三明 南平 龙岩
  • 天津
  • 云南
  • 昆明 红河 大理 文山 德宏 曲靖 昭通 楚雄 保山 玉溪 丽江 临沧 思茅 西双版纳 怒江 迪庆
  • 四川
  • 成都 绵阳 广元 达州 南充 德阳 广安 阿坝 巴中 遂宁 内江 凉山 攀枝花 乐山 自贡 泸州 雅安 宜宾 资阳 眉山 甘孜
  • 广西
  • 贵港 玉林 北海 南宁 柳州 桂林 梧州 钦州 来宾 河池 百色 贺州 崇左 防城港
  • 安徽
  • 芜湖 合肥 六安 宿州 阜阳 安庆 马鞍山 蚌埠 淮北 淮南 宣城 黄山 铜陵 亳州 池州 巢湖 滁州
  • 海南
  • 三亚 海口 琼海 文昌 东方
  • 江西
  • 南昌 赣州 上饶 吉安 九江 新余 抚州 宜春 景德镇 萍乡 鹰潭
  • 湖北
  • 武汉 宜昌 襄樊 荆州 恩施 孝感 黄冈 十堰 咸宁 黄石 仙桃 随州 天门 荆门 潜江 鄂州 神农架
  • 山西
  • 太原 大同 运城 长治 晋城 忻州 临汾 吕梁 晋中 阳泉 朔州
  • 辽宁
  • 大连 沈阳 丹东 辽阳 葫芦岛 锦州 朝阳 营口 鞍山 抚顺 阜新 本溪 盘锦 铁岭
  • 黑龙江
  • 齐齐哈尔 哈尔滨 大庆 佳木斯 双鸭山 牡丹江 鸡西 黑河 绥化 鹤岗 伊春 大兴安岭 七台河
  • 内蒙古
  • 赤峰 包头 通辽 呼和浩特 乌海 鄂尔多斯 呼伦贝尔
  • 贵州
  • 贵阳 黔东 黔南 遵义 黔西 毕节 铜仁 安顺 六盘水
  • 甘肃
  • 兰州 天水 庆阳 武威 酒泉 张掖 陇南 白银 定西 平凉 嘉峪关 临夏 金昌 甘南
  • 青海
  • 西宁 海西 海东 海北 果洛 玉树 黄南
  • 新疆
  • 乌鲁木齐 伊犁 昌吉 石河子 哈密
  • 西藏
  • 拉萨 山南 林芝 日喀则
  • 吉林
  • 长春 白山 白城 延边 松原 辽源 通化 四平
  • 宁夏
  • 银川 吴忠 中卫 石嘴山 固原
SiteMap
网站地图
TAG标签
Copyright © 2017-2025 TYWEB.NET 宿迁腾云网络科技有限公司 ALL RIGHTS RESERVED.   苏ICP备17033535号-1

热门搜索

下载 2025 2026 2024 请输入关健词 货源 货货源 虚拟 禅道
  • 客服

    在线客服

  • 电话

    13160355545

  • 微信

精品模板
建站费用
成功案例
联系我们