算法导论(14)

14.1 动态顺序统计 
顺序统计树(order-statistic tree)只是简单地在每个结点上存储附加信息的一颗红黑树,使得可以在O(logn)时间内确定任何的顺序统计量。

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">struct node
{
    int key,color,size;
    node <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>left,<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>right,<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>p;
    node():color(BLACK){}
};

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//查找具有给定秩的元素,时间复杂度为O(logn)。</span>
node <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>OSSelect(node <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>x,int i)
{
    int r<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>left<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>size<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">+</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(i<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">==</span>r)<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> x;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(i<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>r)<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> OSSelect(x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>left,i);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> OSSelect(x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>right,i<span class="hljs-attribute" style="box-sizing: border-box;">-r</span>);
}

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//确定一个元素的秩,时间复杂度为O(logn)。</span>
int OSRank(node <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>root,node <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>x)
{
    int r<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>left<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>size<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">+</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
    node <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>y<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>x;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span>(y<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span>root)
    {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(y<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">==</span>y<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>p<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>right)r<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">+=</span>y<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>p<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>left<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>size<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">+</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
        y<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>y<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>p;
    }
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> r;
}

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//对子树规模的维护</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//(1)插入:对由根至叶子的路径上遍历的每一个结点x,都增加x->size属性。新增加结点的size为1。</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//(2)删除:我们只需要遍历一条由结点y(从它在树中的原始位置开始)至根的简单路径,并减少路径上每个结点的size属性的值。</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//(3)在左旋和右旋中增加下面两行。</span>
y<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>size<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>size;
x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>size<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>left<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>size<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">+</span>x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>right<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>size<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">+</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li></ul>

14.2 如何扩张数据结构

14.3 区间树 
区间树(interval tree)是一种对动态集合进行维护的红黑树。

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">struct node
{
    int key,color;
    node <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>left,<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>right,<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>p;
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">pair</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>int,int<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> int;
    node():color(BLACK){}
};

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//判断i和j是否重叠。</span>
bool overlap(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">pair</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>int,int<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> i,<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">pair</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>int,int<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> j)
{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> i<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>first<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>j<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>second<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&&</span>j<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>first<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>i<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>second;
}

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//返回一个指向区间树中元素x的指针,使x->int与i重叠;若此元素不存在,则返回nil。时间复杂度为O(logn)。</span>
node <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>intervalSearch(node <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>root,<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">pair</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>int,int<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> i)
{
    node <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>root;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span>(x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span>nil<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&&</span>overlap(i,x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>int))
    {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>left<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span>nil<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&&</span>x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>left<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">max</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">>=</span>i<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>first)x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>left;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>right;
    }
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> x;
}

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//对信息的维护</span>
x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">max</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">max</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">max</span>(x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>int<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>second,x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>left<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">max</span>),x<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>right<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">max</span>);</code>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值