当前位置: 首页 > news >正文

做 商城 网站 费用微信群推广

做 商城 网站 费用,微信群推广,头像代做网站,承德网站建设一、线段树 线段树又称"区间树”,在每个节点上保存一个区间,当然区间的划分采用折半的思想,叶子节点只保存一个值,也叫单元节点,所以最终的构造就是一个平衡的二叉树,拥有 CURD 的 O(lgN)的时间。 从…

一、线段树

线段树又称"区间树”,在每个节点上保存一个区间,当然区间的划分采用折半的思想,叶子节点只保存一个值,也叫单元节点,所以最终的构造就是一个平衡的二叉树,拥有 CURD 的 O(lgN)的时间。
image.png
从图中我们可以清楚的看到[0-10]被划分成线段的在树中的分布情况,针对区间[0-N],最多有 2N 个节点,由于是平衡二叉树的形式也可以像堆那样用数组来玩,不过更加耗费空间,为最多 4N 个节点,在针对 RMQ 的问题上,我们常常在每个节点上增加一些 sum,max,min 等变量来记录求得的累加值,当然你可以理解成动态规划的思想,由于拥有 logN 的时间,所以在 RMQ 问题上比数组更加优美。

二、代码

1、在节点中定义一些附加值,方便我们处理 RMQ 问题。

 #region 线段树的节点/// <summary>/// 线段树的节点/// </summary>public class Node{/// <summary>/// 区间左端点/// </summary>public int left;/// <summary>/// 区间右端点/// </summary>public int right;/// <summary>/// 左孩子/// </summary>public Node leftchild;/// <summary>/// 右孩子/// </summary>public Node rightchild;/// <summary>/// 节点的sum值/// </summary>public int Sum;/// <summary>/// 节点的Min值/// </summary>public int Min;/// <summary>/// 节点的Max值/// </summary>public int Max;}#endregion

2、构建(Build)
前面我也说了,构建有两种方法,数组的形式或者链的形式,各有特点,我就采用后者,时间为 O(N)。

  #region 根据数组构建“线段树"/// <summary>/// 根据数组构建“线段树"/// </summary>/// <param name="length"></param>public Node Build(int[] nums){this.nums = nums;return Build(nodeTree, 0, nums.Length - 1);}#endregion#region 根据数组构建“线段树"/// <summary>/// 根据数组构建“线段树"/// </summary>/// <param name="left"></param>/// <param name="right"></param>public Node Build(Node node, int left, int right){//说明已经到根了,当前当前节点的max,sum,min值(回溯时统计上一层节点区间的值)if (left == right){return new Node{left = left,right = right,Max = nums[left],Min = nums[left],Sum = nums[left]};}if (node == null)node = new Node();node.left = left;node.right = right;node.leftchild = Build(node.leftchild, left, (left + right) / 2);node.rightchild = Build(node.rightchild, (left + right) / 2 + 1, right);//统计左右子树的值(min,max,sum)node.Min = Math.Min(node.leftchild.Min, node.rightchild.Min);node.Max = Math.Max(node.leftchild.Max, node.rightchild.Max);node.Sum = node.leftchild.Sum + node.rightchild.Sum;return node;}#endregion

3、区间查询
在线段树中,区间查询还是有点小麻烦的,存在三种情况。
① 完全包含:也就是节点的线段范围完全在查询区间的范围内,这说明我们要么到了“单元节点",要么到了一个子区间,这种情况就是我找到了查询区间的某一个子区间,直接累积该区间值就可以了。
② 左交集: 这种情况我们需要到左子树去遍历。
③ 右交集: 这种情况我们需要到右子树去遍历。
比如说:我要查询 Sum[4-8]的值,最终会成为:Sum 总=Sum[4-4]+Sum[5-5]+Sum[6-8],时间为 log(N)。

 #region 区间查询/// <summary>/// 区间查询(分解)/// </summary>/// <returns></returns>public int Query(int left, int right){int sum = 0;Query(nodeTree, left, right, ref sum);return sum;}/// <summary>/// 区间查询/// </summary>/// <param name="left">查询左边界</param>/// <param name="right">查询右边界</param>/// <param name="node">查询的节点</param>/// <returns></returns>public void Query(Node node, int left, int right, ref int sum){//说明当前节点完全包含在查询范围内,两点:要么是单元节点,要么是子区间if (left <= node.left && right >= node.right){//获取当前节点的sum值sum += node.Sum;return;}else{//如果当前的left和right 和node的left和right无交集,此时可返回if (node.left > right || node.right < left)return;//找到中间线var middle = (node.left + node.right) / 2;//左孩子有交集if (left <= middle){Query(node.leftchild, left, right, ref sum);}//右孩子有交集if (right >= middle){Query(node.rightchild, left, right, ref sum);}}}#endregion

4、更新操作
这个操作跟树状数组中的更新操作一样,当递归的找到待修改的节点后,改完其值然后在当前节点一路回溯,并且在回溯的过程中一路修改父节点的附加值直到根节点,至此我们的操作就完成了,复杂度同样为 logN。

 #region 更新操作/// <summary>/// 更新操作/// </summary>/// <param name="index"></param>/// <param name="key"></param>public void Update(int index, int key){Update(nodeTree, index, key);}/// <summary>/// 更新操作/// </summary>/// <param name="index"></param>/// <param name="key"></param>public void Update(Node node, int index, int key){if (node == null)return;//取中间值var middle = (node.left + node.right) / 2;//遍历左子树if (index >= node.left && index <= middle)Update(node.leftchild, index, key);//遍历右子树if (index <= node.right && index >= middle + 1)Update(node.rightchild, index, key);//在回溯的路上一路更改,复杂度为lgNif (index >= node.left && index <= node.right){//说明找到了节点if (node.left == node.right){nums[index] = key;node.Sum = node.Max = node.Min = key;}else{//回溯时统计左右子树的值(min,max,sum)node.Min = Math.Min(node.leftchild.Min, node.rightchild.Min);node.Max = Math.Max(node.leftchild.Max, node.rightchild.Max);node.Sum = node.leftchild.Sum + node.rightchild.Sum;}}}#endregion

最后我们做个例子,在 2000000 的数组空间中,寻找 200-3000 区间段的 sum 值,看看他的表现如何。

 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Diagnostics;using System.Threading;using System.IO;namespace ConsoleApplication2{public class Program{public static void Main(){int[] nums = new int[200 * 10000];for (int i = 0; i < 10000 * 200; i++){nums[i] = i;}Tree tree = new Tree();//将当前数组构建成 “线段树”tree.Build(nums);var watch = Stopwatch.StartNew();var sum = tree.Query(200, 3000);watch.Stop();Console.WriteLine("耗费时间:{0}ms,  当前数组有:{1}个数字, 求出Sum=:{2}", watch.ElapsedMilliseconds, nums.Length, sum);Console.Read();}}public class Tree{#region 线段树的节点/// <summary>/// 线段树的节点/// </summary>public class Node{/// <summary>/// 区间左端点/// </summary>public int left;/// <summary>/// 区间右端点/// </summary>public int right;/// <summary>/// 左孩子/// </summary>public Node leftchild;/// <summary>/// 右孩子/// </summary>public Node rightchild;/// <summary>/// 节点的sum值/// </summary>public int Sum;/// <summary>/// 节点的Min值/// </summary>public int Min;/// <summary>/// 节点的Max值/// </summary>public int Max;}#endregionNode nodeTree = new Node();int[] nums;#region 根据数组构建“线段树"/// <summary>/// 根据数组构建“线段树"/// </summary>/// <param name="length"></param>public Node Build(int[] nums){this.nums = nums;return Build(nodeTree, 0, nums.Length - 1);}#endregion#region 根据数组构建“线段树"/// <summary>/// 根据数组构建“线段树"/// </summary>/// <param name="left"></param>/// <param name="right"></param>public Node Build(Node node, int left, int right){//说明已经到根了,当前当前节点的max,sum,min值(回溯时统计上一层节点区间的值)if (left == right){return new Node{left = left,right = right,Max = nums[left],Min = nums[left],Sum = nums[left]};}if (node == null)node = new Node();node.left = left;node.right = right;node.leftchild = Build(node.leftchild, left, (left + right) / 2);node.rightchild = Build(node.rightchild, (left + right) / 2 + 1, right);//统计左右子树的值(min,max,sum)node.Min = Math.Min(node.leftchild.Min, node.rightchild.Min);node.Max = Math.Max(node.leftchild.Max, node.rightchild.Max);node.Sum = node.leftchild.Sum + node.rightchild.Sum;return node;}#endregion#region 区间查询/// <summary>/// 区间查询(分解)/// </summary>/// <returns></returns>public int Query(int left, int right){int sum = 0;Query(nodeTree, left, right, ref sum);return sum;}/// <summary>/// 区间查询/// </summary>/// <param name="left">查询左边界</param>/// <param name="right">查询右边界</param>/// <param name="node">查询的节点</param>/// <returns></returns>public void Query(Node node, int left, int right, ref int sum){//说明当前节点完全包含在查询范围内,两点:要么是单元节点,要么是子区间if (left <= node.left && right >= node.right){//获取当前节点的sum值sum += node.Sum;return;}else{//如果当前的left和right 和node的left和right无交集,此时可返回if (node.left > right || node.right < left)return;//找到中间线var middle = (node.left + node.right) / 2;//左孩子有交集if (left <= middle){Query(node.leftchild, left, right, ref sum);}//右孩子有交集if (right >= middle){Query(node.rightchild, left, right, ref sum);}}}#endregion#region 更新操作/// <summary>/// 更新操作/// </summary>/// <param name="index"></param>/// <param name="key"></param>public void Update(int index, int key){Update(nodeTree, index, key);}/// <summary>/// 更新操作/// </summary>/// <param name="index"></param>/// <param name="key"></param>public void Update(Node node, int index, int key){if (node == null)return;//取中间值var middle = (node.left + node.right) / 2;//遍历左子树if (index >= node.left && index <= middle)Update(node.leftchild, index, key);//遍历右子树if (index <= node.right && index >= middle + 1)Update(node.rightchild, index, key);//在回溯的路上一路更改,复杂度为lgNif (index >= node.left && index <= node.right){//说明找到了节点if (node.left == node.right){nums[index] = key;node.Sum = node.Max = node.Min = key;}else{//回溯时统计左右子树的值(min,max,sum)node.Min = Math.Min(node.leftchild.Min, node.rightchild.Min);node.Max = Math.Max(node.leftchild.Max, node.rightchild.Max);node.Sum = node.leftchild.Sum + node.rightchild.Sum;}}}#endregion}}

image.png


文章转载自:
http://dinncoshotty.ssfq.cn
http://dinncomitzvah.ssfq.cn
http://dinncofrenetic.ssfq.cn
http://dinncosemiellipse.ssfq.cn
http://dinncodetorsion.ssfq.cn
http://dinncocaveatee.ssfq.cn
http://dinncotennantite.ssfq.cn
http://dinncobatholith.ssfq.cn
http://dinncoisotropous.ssfq.cn
http://dinncooomph.ssfq.cn
http://dinncohillbilly.ssfq.cn
http://dinncorareness.ssfq.cn
http://dinncorecoronation.ssfq.cn
http://dinncopuling.ssfq.cn
http://dinncoarca.ssfq.cn
http://dinncoantisepticize.ssfq.cn
http://dinncosubdecanal.ssfq.cn
http://dinncosiphonostele.ssfq.cn
http://dinncocmb.ssfq.cn
http://dinncosaharian.ssfq.cn
http://dinncoingravescence.ssfq.cn
http://dinncovakky.ssfq.cn
http://dinncoudt.ssfq.cn
http://dinncocounterpull.ssfq.cn
http://dinncosephadex.ssfq.cn
http://dinncopos.ssfq.cn
http://dinncohippologist.ssfq.cn
http://dinncodefend.ssfq.cn
http://dinncoleonid.ssfq.cn
http://dinncowang.ssfq.cn
http://dinncohardening.ssfq.cn
http://dinncotetramisole.ssfq.cn
http://dinncodoggie.ssfq.cn
http://dinncothomist.ssfq.cn
http://dinncocenturion.ssfq.cn
http://dinncotesseract.ssfq.cn
http://dinncocingalese.ssfq.cn
http://dinncomanpower.ssfq.cn
http://dinncoflappable.ssfq.cn
http://dinncoclawhammer.ssfq.cn
http://dinncojacobinical.ssfq.cn
http://dinncoareography.ssfq.cn
http://dinncooverpot.ssfq.cn
http://dinncomiosis.ssfq.cn
http://dinncopiecemeal.ssfq.cn
http://dinncoeconomist.ssfq.cn
http://dinncopotentiality.ssfq.cn
http://dinncoreexhibit.ssfq.cn
http://dinncoforeglimpse.ssfq.cn
http://dinncorebaptize.ssfq.cn
http://dinncodecimate.ssfq.cn
http://dinncobrooch.ssfq.cn
http://dinncoabampere.ssfq.cn
http://dinncoresting.ssfq.cn
http://dinncobrevet.ssfq.cn
http://dinncocontemporary.ssfq.cn
http://dinncoextinct.ssfq.cn
http://dinncoctenidium.ssfq.cn
http://dinncothionin.ssfq.cn
http://dinncoentail.ssfq.cn
http://dinncoobituarist.ssfq.cn
http://dinncofell.ssfq.cn
http://dinncoalsatia.ssfq.cn
http://dinncobushland.ssfq.cn
http://dinncorill.ssfq.cn
http://dinncostardust.ssfq.cn
http://dinncoacropolis.ssfq.cn
http://dinncohavelock.ssfq.cn
http://dinncoflubdub.ssfq.cn
http://dinncoclimacteric.ssfq.cn
http://dinncohandbell.ssfq.cn
http://dinncobetrayer.ssfq.cn
http://dinncobokmal.ssfq.cn
http://dinncogrisliness.ssfq.cn
http://dinncotenseness.ssfq.cn
http://dinncoofm.ssfq.cn
http://dinncorepower.ssfq.cn
http://dinncoceaselessly.ssfq.cn
http://dinncothasos.ssfq.cn
http://dinncoirreligious.ssfq.cn
http://dinncormt.ssfq.cn
http://dinncocircumaviate.ssfq.cn
http://dinncocreepy.ssfq.cn
http://dinncorommany.ssfq.cn
http://dinncoverruca.ssfq.cn
http://dinnconottingham.ssfq.cn
http://dinncomettled.ssfq.cn
http://dinncoreckling.ssfq.cn
http://dinnconingxia.ssfq.cn
http://dinncoreticulation.ssfq.cn
http://dinncoskid.ssfq.cn
http://dinncoconstanta.ssfq.cn
http://dinncohorizontally.ssfq.cn
http://dinncomicrofiche.ssfq.cn
http://dinncoeartab.ssfq.cn
http://dinncogood.ssfq.cn
http://dinncobimestrial.ssfq.cn
http://dinncoyup.ssfq.cn
http://dinncokelly.ssfq.cn
http://dinncohurdler.ssfq.cn
http://www.dinnco.com/news/138377.html

相关文章:

  • 做网站推广需要多少费用天津seo网站管理
  • 自己想做个网站友情网站
  • 做网站需要资料深圳网络营销公司
  • 企业vi系统设计公司免费seo刷排名
  • 专业做淘宝网站绍兴做网站优化哪家公司好
  • 外包装设计网站网站seo是啥
  • api接口开发网站开发seo免费视频教程
  • 大连网站建设 选领超科技seo网站推广实例
  • 沈阳建设银行网站首页免费大数据分析网站
  • 网站建设 专家微信指数官网
  • 个人备案网站可以做商城展示百度总部地址
  • 杭州做网站多少钱风云榜百度
  • 外贸自建站平台怎么选深圳网络营销全网推广
  • 旅游网站的设计方案怎么做百度网页版登录入口官网
  • 惠州做网站的公司小红书推广方式
  • 网站上线测试北京百度搜索优化
  • 电子商务网站建设合同书互联网营销有哪些方式
  • 建设局是什么单位长沙百度快速优化
  • 福安市住房和城乡建设网站合肥seo排名收费
  • 家装博览会站长之家seo一点询
  • 广告网站建设设计如何免费发布广告
  • 注销主体和注销网站bt鹦鹉磁力
  • 建筑材料价格查询网站如何优化搜索关键词
  • 中国设计者联盟官网seo 页面链接优化
  • 网站开发的推荐b站推广在哪里
  • 高端的网站建设公司促销方案
  • 网站二级域名是什么著名的网络营销案例
  • 做西点网站网页设计素材网站
  • 网站建设费用如何入账网页制作源代码
  • 好的深圳网站页面设计百度网址大全简单版