在树形选择排序中,利用锦标赛思想建立的树称为胜者树。

1、每个非终端节点存储的是左右孩子节点中的优胜者。

2、通过减少比较次数,提高效率。

3、胜者树就是一颗特殊的线段树。

一、构建树

Procedure buildmint;  复杂度 O(n)
var i,j,k:longint;
begin
  i:=N; j:=N+n-; { 其中 N 为大于等于 n 的最小 2 次方数 }
  while i> do
  begin
    k:=i;
    while k<j do
    begin
      f[k div ]:=min(f[k],f[k+]);
      k:=k+;
    end;
    if j and = then f[j div ]:=f[j];
    i:=i div ; j:=j div ;
  end;
end;

二、查询

核心思想:自下向上,奇偶缩进。

Function findmin(x,y:longint):longint;  复杂度 O(logn)
var i,j,k,r:longint;
begin
  i:=x+N-; j:=y+N-; r:=i;
  while i<=j do
  begin
    if (f[r]>f[i]) then r:=i;
    if (f[r]>f[j]) then r:=j;
    if (i and =) then inc(i);
    if (j and =) then dec(j);
    i:=i shr ; j:=j shr ;
  end; exit(f[r]);
  while r<N do
  if (f[r]=f[r*]) then r:=r* else r:=r*+;
  exit(r-N+);
end;

三、更新

核心思想:自下而上,更新父节点。

胜者树不擅长更新,因为,某个结点更新的时候,它还需要跟兄弟结点比较。更新频繁的情况,用败者树。

四、败者树

败者树是胜者树的一种变体。在败者树中,用父结点记录其左右子结点进行比赛的败者,而让胜者参加下一轮的比赛。败者树的根结点记录的是败者,需要加一个结点来记录整个比赛的胜利者。采用败者树可以简化重构的过程。

典型应用:多路归并排序,可以减少比较次数。

五、代码实现胜者树

poj2328 http://poj.org/problem?id=2823

Description

An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves rightwards by one position. Following is an example: 
The array is [1 3 -1 -3 5 3 6 7], and k is 3.

Window position Minimum value Maximum value
[1  3  -1] -3  5  3  6  7  -1 3
 1 [3  -1  -3] 5  3  6  7  -3 3
 1  3 [-1  -3  5] 3  6  7  -3 5
 1  3  -1 [-3  5  3] 6  7  -3 5
 1  3  -1  -3 [5  3  6] 7  3 6
 1  3  -1  -3  5 [3  6  7] 3 7

Your task is to determine the maximum and minimum values in the sliding window at each position.

Input

The input consists of two lines. The first line contains two integers n and k which are the lengths of the array and the sliding window. There are n integers in the second line. 

Output

There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values. 

Sample Input

8 3
1 3 -1 -3 5 3 6 7

Sample Output

-1 -3 -3 -3 3 3
3 3 5 5 6 7

Source

#include <iostream>
#include <cmath> using namespace std; const int MX = ; int n, k;
int a[MX], minRes[MX], maxRes[MX];
int treeMin[*MX], treeMax[*MX];
int N; //构建一颗winner tree,tree用数组存储,根结点是数组的第二个结点,即A[1]
//叶子结点是原始数组。树的最左结点的下标是2的指数
void build() {
int i = N, j = N+n-;
while (i > ) {
int t = i;
while (t < j) {
treeMin[t/] = min(treeMin[t], treeMin[t+]);
treeMax[t/] = max(treeMax[t], treeMax[t+]);
t += ;
}
if ((j&) == ) {//下标j是偶数,说明这个结点是落单的
treeMin[j/] = treeMin[j];
treeMax[j/] = treeMax[j];
}
i = i>>;
j = j>>;
}
} int query(int x, int y) {
int i=x+N, j=y+N, t = i;
while (i <= j) {
if (treeMin[t] > treeMin[i]) t = i;
if (treeMin[t] > treeMin[j]) t = j;
if ((i&) == ) i++;
if ((j&) == ) j--;
i = i>>;
j = j>>;
}
//return treeMin[t];
while (t < N) {
if (treeMin[t] == treeMin[t*]) t = t*;
else t = t*+;
}
return treeMin[t];
//return t - N;
} void work() {
for (int i=; i<n-k+; i++) {
int x=N+i, y=x+k-, t=x, r=x;
while (x<=y) {
if (treeMin[t] > treeMin[x]) t = x;
if (treeMin[t] > treeMin[y]) t = y;
if (treeMax[r] < treeMax[x]) r = x;
if (treeMax[r] < treeMax[y]) r = y;
if ((x&) == ) x++;
if ((y&) == ) y--;
x = x>>;
y = y>>;
}
minRes[i] = treeMin[t];
maxRes[i] = treeMax[r];
}
} void printRes() {
for (int i=; i<n-k+; i++) {
if (i!=) cout<<" ";
cout<<minRes[i];
}
cout<<endl;
for (int i=; i<n-k+; i++) {
if (i!=) cout<<" ";
cout<< maxRes[i];
}
cout<<endl;
} int calN(int x) {
int i = ;
while (i < x) {
i = i<<;
}
return i;
} void printTree() {
cout << "min winner tree:" << endl;
for (int i=; i< n+N; i++) {
cout << treeMin[i] << " ";
}
cout << endl << "max winner tree:" << endl;
for (int i=; i<n + N; i++) {
cout << treeMax[i] << " ";
}
cout << endl;
} int main()
{
cin >> n >> k;
N = calN(n);
for (int i=; i<n; i++) {
cin >> a[i];
treeMax[N+i] = treeMin[N+i] = a[i];
} build(); //printTree(); work();
printRes(); //cout<<"query:"<< query(0, 2)<<endl; //cout << "Hello world!" << endl;
return ;
}

winner tree 胜者树的更多相关文章

  1. Mysql存储引擎之TokuDB以及它的数据结构Fractal tree(分形树)

    在目前的Mysql数据库中,使用最广泛的是innodb存储引擎.innodb确实是个很不错的存储引擎,就连高性能Mysql里都说了,如果不是有什么很特别的要求,innodb就是最好的选择.当然,这偏文 ...

  2. 页面设计--Tree目录树

    Tree目录树控件属性: 根据数据集合来配置相应的信息 加载模式有自动加载.自定加载 web中显示效果图:

  3. [转] Splay Tree(伸展树)

    好久没写过了,比赛的时候就调了一个小时,差点悲剧,重新复习一下,觉得这个写的很不错.转自:here Splay Tree(伸展树) 二叉查找树(Binary Search Tree)能够支持多种动态集 ...

  4. CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划)

    CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划) Description 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的 ...

  5. 【数据结构】B-Tree, B+Tree, B*树介绍 转

    [数据结构]B-Tree, B+Tree, B*树介绍 [摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是浮云,目前Mysql的MyISAM和InnoDB都支持B-Tre ...

  6. poj 1741 Tree(树的点分治)

    poj 1741 Tree(树的点分治) 给出一个n个结点的树和一个整数k,问有多少个距离不超过k的点对. 首先对于一个树中的点对,要么经过根结点,要么不经过.所以我们可以把经过根节点的符合点对统计出 ...

  7. 【POJ 2486】 Apple Tree(树型dp)

    [POJ 2486] Apple Tree(树型dp) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8981   Acce ...

  8. C++胜者树

    #include <iostream> #define MAX_VALUE 0x7fffffff using namespace std; //在这里我先反思一下.不知道怎么搞的,这个算法 ...

  9. MYSQL的B+Tree索引树高度如何计算

    前一段被问到一个平时没有关注到有关于MYSQL索引相关的问题点,被问到一个表有3000万记录,假如有一列占8位字节的字段,根据这一列建索引的话索引树的高度是多少? 这一问当时就被问蒙了,平时这也只关注 ...

随机推荐

  1. TextView实现圆角效果

    自定义一个Xml样式: <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android ...

  2. OAuth2.0协议

    简介  OAuth(Open Authorization),协议为用户资源的授权提供了一个安全的.开放而又简易的标准.与以往的授权方式不同之处是OAuth的授权不会使第三方触及到用户的帐号信息(如用户 ...

  3. 一些需要被禁用的php危险函数

    phpinfo() 功能描述:输出 PHP 环境信息以及相关的模块、WEB 环境等信息。 危险等级:中 passthru() 功能描述:允许执行一个外部程序并回显输出,类似于 exec()。 危险等级 ...

  4. Android之Fragment学习笔记②(Fragment生命周期)

    一. Fragment生命周期图                                  二.Fragment生命周期方法介绍 Fragment的生命周期和activity生命周期很像,其生 ...

  5. 一个比较轻巧好用的js分页插件,可ajax可url

    var pageNav = pageNav || {}; pageNav.fn = null; pageNav.pre = "pre"; pageNav.next = " ...

  6. css 鼠标移动到按钮图片改变;图片换层;鼠标放上透明度改变直到隐藏;

    css 鼠标移动到按钮图片改变: 方法一: <style> .pp a { width:575px; height:157px; background:url(1.jpg);/*图片地址* ...

  7. Linux下编译静态MinGW环境,编译windows平台Qt程序(使用MXE)

    参考链接: MXE.>大多数程序都是在windows平台下开发的程序.windows 在现实中也是绕不过的一个系统平台,做为受过几年VC,MFC”虐待”的程序员,在做为一个程序员之前是一位Lin ...

  8. QTextCodec::makeDecoder函数,plugins需要是动态链接库

    QT中的QString内容使用Unicode作为文本编码.但是实际系统中通常采用的是其他编码,例如GBK,utf8等.为了便于兼容这些格式,QT中还设置了两个字符串类型: QCString类: C类型 ...

  9. 用户交互与while循环<代码>

    #用户交互1 age_oldboy = 56 guess_age = int(input(">>:")) if guess_age == age_oldboy: pri ...

  10. [LeetCode]题解(python):052-N-Queens II

    题目来源 https://leetcode.com/problems/n-queens-ii/ Follow up for N-Queens problem. Now, instead outputt ...