网络子系统40_inet_peer平衡二叉树的插入




// 遍历二叉树路径
// 宏的主要任务:
// 1.遍历到达目标节点的路径
// 2.将路径上经过的节点保存在stack中
// 3.栈顶为peer_avl_empty
// 4.stackptr指向下一个空闲的位置
1.2 #define lookup(_daddr,_stack) \
({ \
struct inet_peer *u, **v; \
if (_stack != NULL) { \
stackptr = _stack;//栈指针指向栈底 \
*stackptr++ = &peer_root;//栈底为root,移动栈指针 \
} \
for (u = peer_root; u != peer_avl_empty; ) { \
if (_daddr == u->v4daddr) \
break; \
if ((__force __u32)_daddr < (__force __u32)u->v4daddr) \
v = &u->avl_left; \
else \
v = &u->avl_right; \
if (_stack != NULL) \
*stackptr++ = v; \
u = *v; \
} \
u; \
})
// 插入平衡二叉树
// 注:新节点的初始化为1
#define link_to_pool(n) \
do { \
n->avl_height = 1; \
n->avl_left = peer_avl_empty; //左右均为empty \
n->avl_right = peer_avl_empty; \
**--stackptr = n; //通过将节点压入栈顶,完成插入操作 \
peer_avl_rebalance(stack, stackptr);//调整二叉树平衡 \
} while(0)
// 平衡二叉树
// 参数:
// stack,寻找目标节点时路径上经过的所有节点
// stackend,栈顶指针
1.3 static void peer_avl_rebalance(struct inet_peer **stack[],
struct inet_peer ***stackend)
{
struct inet_peer **nodep, *node, *l, *r;
int lh, rh;
while (stackend > stack) {//stackend指向的节点非根节点
nodep = *--stackend;//nodep为指向要插入节点的父节点的指针
node = *nodep;//父节点的指针
l = node->avl_left;//父节点的左孩子
r = node->avl_right;//右孩子
lh = node_height(l);//高度
rh = node_height(r);
if (lh > rh + 1) { //根平衡因子变为2
struct inet_peer *ll, *lr, *lrl, *lrr;
int lrh;
ll = l->avl_left;//根的左孩子的左孩子
lr = l->avl_right;//根的左孩子的右孩子
lrh = node_height(lr);//左孩子的右孩子的高度
if (lrh <= node_height(ll)) { //并且是在左孩子的左子树插入节点,RR,情况1.1
node->avl_left = lr; /* lr: RH or RH+1 */
node->avl_right = r; /* r: RH */
node->avl_height = lrh + 1; /* RH+1 or RH+2 */
l->avl_left = ll; /* ll: RH+1 */
l->avl_right = node; /* node: RH+1 or RH+2 */
l->avl_height = node->avl_height + 1;
*nodep = l; //左孩子成为
} else { //并且是在左孩子的右子树插入节点,LL,RR,情况1.2
lrl = lr->avl_left; /* lrl: RH or RH-1 */
lrr = lr->avl_right; /* lrr: RH or RH-1 */
node->avl_left = lrr; /* lrr: RH or RH-1 */
node->avl_right = r; /* r: RH */
node->avl_height = rh + 1; /* node: RH+1 */
l->avl_left = ll; /* ll: RH */
l->avl_right = lrl; /* lrl: RH or RH-1 */
l->avl_height = rh + 1; /* l: RH+1 */
lr->avl_left = l; /* l: RH+1 */
lr->avl_right = node; /* node: RH+1 */
lr->avl_height = rh + 2;
*nodep = lr; //左孩子的右子树根成为当前的根节点
}
} else if (rh > lh + 1) { //根平衡因子变为-2
struct inet_peer *rr, *rl, *rlr, *rll;
int rlh;
rr = r->avl_right;
rl = r->avl_left;
rlh = node_height(rl);
if (rlh <= node_height(rr)) { //在右孩子的右子树上插入节点,LL,情况1.3
node->avl_right = rl; /* rl: LH or LH+1 */
node->avl_left = l; /* l: LH */
node->avl_height = rlh + 1; /* LH+1 or LH+2 */
r->avl_right = rr; /* rr: LH+1 */
r->avl_left = node; /* node: LH+1 or LH+2 */
r->avl_height = node->avl_height + 1;
*nodep = r;//右孩子作为根节点
} else { //在右孩子的左子树上插入节点,RR,LL,情况1.4
rlr = rl->avl_right; /* rlr: LH or LH-1 */
rll = rl->avl_left; /* rll: LH or LH-1 */
node->avl_right = rll; /* rll: LH or LH-1 */
node->avl_left = l; /* l: LH */
node->avl_height = lh + 1; /* node: LH+1 */
r->avl_right = rr; /* rr: LH */
r->avl_left = rlr; /* rlr: LH or LH-1 */
r->avl_height = lh + 1; /* r: LH+1 */
rl->avl_right = r; /* r: LH+1 */
rl->avl_left = node; /* node: LH+1 */
rl->avl_height = lh + 2;
*nodep = rl; //右孩子的左子树根作为当前的根节点
}
} else {//平衡因子为0,1,-1
node->avl_height = (lh > rh ? lh : rh) + 1;
}
}
}
最后更新:2017-04-03 14:53:37