RB树插入顺序灵敏度

时间:2013-04-07 02:50:03

标签: ruby algorithm tree binary-tree binary-search-tree

给定整数间隔I,RB树R具有来自n的{​​{1}}个唯一元素和I的序列S来自n的{​​{1}}的唯一元素,I插入R的效果会根据S是排序还是随机而有所不同订购?答案如何根据RS

的相对大小而有所不同

鉴于|I|的元素不在n中,不清楚如何分析插入需要维护的不变量以及需要发生的重新平衡操作。我在SR大100倍的情况下运行的Ruby基准测试表明排序插入的速度提高了10 +%。

2 个答案:

答案 0 :(得分:1)

表现会有所不同。

C ++中的示例测试(我知道g ++的map基于红黑树并使用它):

#include <iostream>
#include <map>
#include <cstdlib>
#include <ctime>

using namespace std;

const int N = 50000;
const int REPS = 100;
int ints[N];

int main()
{
  time_t t;
  srand(time(0));

  // fill ints[] with ints from 0 to N-1
  for (int i = 0; i < N; i++)
    ints[i] = i;

  // randomly shuffle ints[]
  for (int i = 0; i < N; i++)
  {
    int j = ((unsigned)rand() * rand()) % N;
    int t = ints[i];
    ints[i] = ints[j];
    ints[j] = t;
  }

  cout << "Inserting " << 2 * N << " sorted keys, repeating " << REPS << " times..." << endl;
  time(&t); cout << ctime(&t) << endl;
  for (int n = 0; n < REPS; n++)
  {
    map<int,int> m;
    for (int i = 0; i < N; i++)
      m[i] = i;
    for (int i = 0; i < N; i++)
      m[N + i] = i;
  }
  time(&t); cout << ctime(&t) << endl;

  cout << "Inserting " << N << " sorted keys and then " << N << " unsorted keys, repeating " << REPS << " times..." << endl;
  time(&t); cout << ctime(&t) << endl;
  for (int n = 0; n < REPS; n++)
  {
    map<int,int> m;
    for (int i = 0; i < N; i++)
      m[i] = i;
    for (int i = 0; i < N; i++)
      m[N + ints[i]] = i;
  }
  time(&t); cout << ctime(&t) << endl;

  return 0;
}

输出(liveworkspace):

Inserting 100000 sorted keys, repeating 100 times...
Sun Apr 7 04:14:03 2013

Sun Apr 7 04:14:05 2013

Inserting 50000 sorted keys and then 50000 unsorted keys, repeating 100 times...
Sun Apr 7 04:14:05 2013

Sun Apr 7 04:14:10 2013

如您所见,性能明显不同:排序插入为2秒,未排序插入为5秒。

答案 1 :(得分:0)

当然表现各不相同;如果你插入2,然后是1,然后将3插入一个空的红黑树,你永远不会执行旋转;如果插入1,然后是2,然后是3,则必须执行旋转。

如果您只想以最快的方式构建一个红黑树,请对列表进行排序,将其拆分为中间元素,从两半构建红黑树,并使中间元素成为两者的父元素半。你在这里没有轮换或其他恶作剧。

像阿列克谢·弗鲁兹(Alexey Frunze)所说,它的变化不会超过一个小的常数因素。