Randomized Binary Search Tree - arosh/arosh.github.com GitHub Wiki

Copy and Pasteでベンチマークしたところ、木の高さはだいたい3*lg(n)くらいに収まった

insert(immutable)とremove(mutable,immutable)のベリファイはできていない

struct T {
  int value;
  int size;
  T *left, *right;
};

typedef pair<T *, T *> P;

// だいたい256MBにおさまる予定
const int NODE_MAX = 10000000;
T node_buf[NODE_MAX];
int node_ptr = 0;

int node_size(T *x) {
  return (x == NULL) ? 0 : x->size;
}

T *update(T *x) {
  x->size = node_size(x->left) + 1 + node_size(x->right);
  return x;
}

T *create(int value, T *left, T *right) {
  if(node_ptr == NODE_MAX) abort();
  T *x = &node_buf[node_ptr++];
  x->value = value;
  x->left = left;
  x->right = right;
  return update(x);
}

T *merge(T *left, T *right, bool immutable) {
  if(left == NULL) return right;
  if(right == NULL) return left;
  int lsize = node_size(left);
  int rsize = node_size(right);
  if(rand() % (lsize + rsize) < lsize) {
    if(immutable) {
      return create(left->value, left->left, merge(left->right, right, immutable));
    }
    else {
      left->right = merge(left->right, right, immutable);
      return update(left);
    }
  }
  else {
    if(immutable) {
      return create(right->value, merge(left, right->left, immutable), right->right);
    }
    else {
      right->left = merge(left, right->left, immutable);
      return update(right);
    }
  }
}

P split(T *x, int pos, bool immutable) {
  if(x == NULL) return P(NULL, NULL);
  if(pos <= node_size(x->left)) {
    P p = split(x->left, pos, immutable);
    if(immutable) {
      return P(p.first, create(x->value, p.second, x->right));
    }
    else {
      x->left = p.second;
      return P(p.first, update(x));
    }
  }
  else {
    P p = split(x->right, pos - 1 - node_size(x->left), immutable);
    if(immutable) {
      return P(create(x->value, x->left, p.first), p.second);
    }
    else {
      x->right = p.first;
      return P(update(x), p.second);
    }
  }
}

int get(T *x, int pos) {
  if(node_size(x->left) == pos) return x->value;
  if(pos <= node_size(x->left)) {
    return get(x->left, pos);
  }
  else {
    return get(x->right, pos - 1 - node_size(x->left));
  }
}

T *insert(T *x, int pos, int value, bool immutable) {
  P p = split(x, pos, immutable);
  return merge(merge(p.first, create(value, NULL, NULL), immutable), p.second, immutable);
}

T *remove(T *x, int pos, bool immutable) {
  P p = split(x, pos, immutable);
  return merge(p.first, split(p.second, 1, immutable).second, immutable);
}
⚠️ **GitHub.com Fallback** ⚠️