从大量集合中构建 AVL 树的高效算法

发布于 08-02 09:10 字数 232 浏览 9 评论 0原文

我有一个很大的 AVL 树,我在程序期间从未排序的集合中构建了几次(它将稍后用于插入/删除项目)。

有没有比在每个项目上使用简单插入更好的算法?首先对集合进行排序,然后尝试以不同的方式构建它会更有效吗?

对我的应用程序的分析表明,该 AVL 大楼是一个热点位置。

I have a large AVL Tree which I build some times during program from an unsorted collection (it will be used to insert/remove items later).

Is there any better algorithm than using the simple insert on each item? Will it be more efficient to sort the collection first and then try to build it differently?

Profiling of my application tells me that this AVL building is a hotspot location.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

川水往事2024-08-09 09:10:26

如果数据可以方便地装入内存,我确实希望首先进行快速排序,然后从中构建树会比执行所有常规插入更快。

要从数组构建树,请以递归方式操作,将树分为三个部分:中间元素、左侧部分和右侧部分;两个部分必须具有相同的大小(+-1),然后用这些部分形成树。这保证了生成的树几乎是平衡的(如果元素的数量是 2^n-1,它将是完美平衡的)。树的创建应该返回树的高度,以便您可以方便地将平衡放入每个节点。

编辑:假设 Ian Piumarta 的 tree.h,我相信这个算法应该可以解决问题:

Node* tree_build(int key[], int value[], int L, int R) // L and R inclusive
{

  int M;
  Node *middle;
  int lh, rh;

  if(L == R)
    return Node_new(key[L], value[L]);

  if(L+1 == R) {
    Node *left = Node_new(key[L], value[L]);
    Node *right = Node_new(key[R], value[R]);
    left->tree.avl_right = right;
    left->tree.avl_height = 1;
    return left;
  }

  // more than two nodes
  M = L + (R-L)/2;
  middle = Node_new(key[M], value[M]);
  middle->tree.avl_left = tree_build(key, value, L, M-1);
  middle->tree.avl_right = tree_build(key, value, M+1, R);
  lh = middle->tree.avl_left->tree.avl_height;
  rh = middle->tree.avl_right->tree.avl_height;
  middle->tree.avl_height = 1 + (lh > rh ? lh:rh);
  return middle;
}

If the data conveniently fit into memory, I would indeed expect that doing a quicksort first, and building the tree from that would be faster than doing all the regular insertions.

To build the tree from an array, operate in a recursive manner, splitting the tree into three parts: a middle element, the left part, and the right part; both parts must have the same size (+-1), then form trees out of these parts. That guarantees that the resulting tree is nearly balanced (it will be perfectly balanced if the number of elements is 2^n-1). Tree creation should return the height of the tree so that you can put the balance conveniently into each node.

Edit: Assuming Ian Piumarta's tree.h, I believe this algorithm should do the trick:

Node* tree_build(int key[], int value[], int L, int R) // L and R inclusive
{

  int M;
  Node *middle;
  int lh, rh;

  if(L == R)
    return Node_new(key[L], value[L]);

  if(L+1 == R) {
    Node *left = Node_new(key[L], value[L]);
    Node *right = Node_new(key[R], value[R]);
    left->tree.avl_right = right;
    left->tree.avl_height = 1;
    return left;
  }

  // more than two nodes
  M = L + (R-L)/2;
  middle = Node_new(key[M], value[M]);
  middle->tree.avl_left = tree_build(key, value, L, M-1);
  middle->tree.avl_right = tree_build(key, value, M+1, R);
  lh = middle->tree.avl_left->tree.avl_height;
  rh = middle->tree.avl_right->tree.avl_height;
  middle->tree.avl_height = 1 + (lh > rh ? lh:rh);
  return middle;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文