网站大量收购独家精品文档,联系QQ:2885784924

划分树(算法总结).pdf

  1. 1、本文档共3页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
划分树(算法总结)

LBoy-1 动态求解区间最大数的问题 揭开它神秘的面纱,探寻真理的奥妙。——小志。 这偏文章主要总结划分树解决区间第K 大数的问题。一些内容并非原创,全部内容只供参考交流! 划分树  划分树的定义 划分树定义为,她的每一个节点保存区间 lft, rht 所有元素,元素排列顺序与原数组(输入)相同,但是, 两个子树的元素为该节点所有元素排序后 rht − lft + 1 / 2个进入左子树,其余的到右子树,同时维护一个 num 域,num[i] 表示lft → i 这些点有多少进入了左子树。(摘自某牛人的博客,为了和下面的算法统一,稍 有变动)  划分树的Sample. 如果由下而上看这个图,我们就会发现他和归并排序的(归并树)的过程很类似,或者说正好相反。归并树 是由下而上的排序,而她确 实由上而下的排序(观察‘4 ’ 的运动轨迹,我们可以猜到, 划分树的排序也是一种稳 定的排序方法,这里不是说 明的重点,不予证明)。但 这正是她可以用来解决第 k 大元素的理由所在。(具体 的理由,写完再补)  划分树的存储结构(采用层次存储结构(由下而上,由左到右,每层两个孩子,见上图) using namespace std; #define M 100001 #define md(x, y) (((x)+(y))1) int sorted[M]; // 对原来集合中的元素排序后的值。 struct node { int val[M]; // val 记录第k 层当前位置的元素的值 int num[M]; // num 记录元素所在区间的当前位置之前进入左孩子的个数 double sum[M]; // sum 记录比当前元素小的元素的和。 }t[20];  划分树的建立Build 划分树的建立和普通的二叉树的建立过程差不多,仍然采取中序的过程(先根节点,然后左右孩子)。 树的建立相对比较简单,我们依据的是已经排好序的位置进行建树,所以先用快排将原集合牌还序。要维护 每个节点的num 域。 void build(int lft, int rht, int p) { if(lft == rht) return; int i, mid = md(lft, rht); int isame = mid - lft + 1, same = 0; /* isame 用来标记和中间值val_mid 相等的,且分到左孩子的数的个数。 LBoy-2 初始时,假定当前区间[lft,rht]有mid-lft+1 个和val_mid 相等。 先踢掉比中间值小的,剩下的就是要插入到左边的*/ for(i = lft; i = rht; i++) if(t[p].val[i] sorted[mid]) isame-- ; int ln = lft, rn = mid + 1; for(i = lft; i = rht; i++) { if(i == lft) { // 初始一个子树。 t[p].num[i] = 0; t[p].sum[i] = 0; } else { // 初始区间下一个节点。 t[p].num[i] = t[p].

文档评论(0)

shaofang00 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档