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

腾云网络 八年经验专注网站建设
  • 首页
  • 服务项目
    • 网站建设
    • 微信小程序
    • 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开发框架流行度排名使用Java进行Web开发的热门品牌Uber,,.流行度php开发框架
  • c++编程初学软件有哪些?--—c++语言最好
  • php文件上传代码WP更新要准时,而且升级就有可能出错!!文件上传下载系统 php
  • 命令行下的php代码格式化工具(命令为一行)
  • php代码注入漏洞微软发布44个漏洞发布安全补丁,7个被评为严重啊d注入工具找网站的漏洞
  • pl/sql 编程语言
  • 过去五年(2015-2019)里编程语言的流行趋势分析
  • 编程语言实现方式(美国)Terence Parr
  • 论坛php网站模板中国最大社区技术及服务商之一推出最新论坛程序软件7.0php 论坛模板
  • 谷歌OS欢迎页面隐含了哪些新线索?(图)

相关

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

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

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

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

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

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

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

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

大会现场蒋涛调查参会者,柳峰解析LBS与智能客服开发重难点?

大会现场蒋涛调查参会者,柳峰解析LBS与智能客服开发重难点?

如何查看php版本?多种方法助你快速知晓

如何查看php版本?多种方法助你快速知晓

PHP格式化:提升代码质量与协作效率的关键规则

如何查看虚拟主机上的 PHP 版本?这篇文章告诉你

Linux 系统管理员和 web 开发者必知:如何查看 PH

Linux 系统管理员和 web 开发者必知:如何查看 PH

标签

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 2024 2026 货源 货货源 虚拟 禅道 报名 金蝶KIS旗舰版
  • 客服

    在线客服

  • 电话

    13160355545

  • 微信

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