網絡子係統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