Lighty的“自适应”树

 

Lighty的“自适应”树

分类: Server Design   369人阅读  评论(2)  收藏  举报

本文原创为freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/article/details/13360863

 

Lighty里采用了“自适应树”,而且是直接借用D. Sleator在1994年实现的代码。

其实,在关键的数据结构上借用历史证明了健壮性的代码比自己重复造轮子要实际得多——如果自己实现,谁能保证这个“新家伙”不会出问题呢?

同样的案例出现在redis里的LZF压缩,pqsort功能等等。

我们来欣赏一下最关键的一个函数——splay。

[html]  view plain copy
  1. /* Splay using the key i (which may or may not be in the tree.)  
  2.  * The starting root is t, and the tree used is defined by rat  
  3.  * size fields are maintained */  
  4. splay_tree * splaytree_splay (splay_tree *t, int i) {  
  5.     splay_tree N, *l, *r, *y;  
  6.     int comp, l_size, r_size;  
  7.   
  8.     if (t == NULL) return t;  
  9.     N.left = N.right = NULL;  
  10.     l = r = &N;  
  11.     l_size = r_size = 0;  
  12.   
  13.     for (;;) {  
  14.         comp = compare(i, t->key);  
  15.         if (comp < 0) {  
  16.             if (t->left == NULL) break;  
  17.             if (compare(i, t->left->key) < 0) {  
  18.                 y = t->left;                           /* rotate right */  
  19.                 t->left = y->right;  
  20.                 y->right = t;  
  21.                 t->size = node_size(t->left) + node_size(t->right) + 1;  
  22.                 t = y;  
  23.                 if (t->left == NULL) break;  
  24.             }  
  25.             r->left = t;                               /* link right */  
  26.             r = t;  
  27.             t = t->left;  
  28.             r_size += 1+node_size(r->right);  
  29.         } else if (comp > 0) {  
  30.             if (t->right == NULL) break;  
  31.             if (compare(i, t->right->key) > 0) {  
  32.                 y = t->right;                          /* rotate left */  
  33.                 t->right = y->left;  
  34.                 y->left = t;  
  35.         t->size = node_size(t->left) + node_size(t->right) + 1;  
  36.                 t = y;  
  37.                 if (t->right == NULL) break;  
  38.             }  
  39.             l->right = t;                              /* link left */  
  40.             l = t;  
  41.             t = t->right;  
  42.             l_size += 1+node_size(l->left);  
  43.         } else {  
  44.             break;  
  45.         }  
  46.     }  
  47.     l_size += node_size(t->left);  /* Now l_size and r_size are the sizes of */  
  48.     r_size += node_size(t->right); /* the left and right trees we just built.*/  
  49.     t->size = l_size + r_size + 1;  
  50.   
  51.     l->right = r->left = NULL;  
  52.   
  53.     /* The following two loops correct the size fields of the right path  */  
  54.     /* from the left child of the root and the right path from the left   */  
  55.     /* child of the root.                                                 */  
  56.     for (y = N.right; y != NULL; y = y->right) {  
  57.         y->size = l_size;  
  58.         l_size -1+node_size(y->left);  
  59.     }  
  60.     for (y = N.left; y != NULL; y = y->left) {  
  61.         y->size = r_size;  
  62.         r_size -1+node_size(y->right);  
  63.     }  
  64.   
  65.     l->right = t->left;                                /* assemble */  
  66.     r->left = t->right;  
  67.     t->left = N.right;  
  68.     t->right = N.left;  
  69.   
  70.     return t;  
  71. }  

自适应树具备与生俱来的“Cache”功能,在处理冷、热分明的数据时,效果非常好。但是,如果数据本身很离散,无任何规律可言,那么,采用这种数据结构会适得其反。这个时候,更好的选择或许是“红黑树”。

 今天就这样吧。早点休息了。

周一没有出去TB,在家休息,反而显得无聊了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值