rripfdb.c
来自「用于嵌入式系统的TCP/IP协议栈及若干服务」· C语言 代码 · 共 2,850 行 · 第 1/5 页
C
2,850 行
while(tmp){ /* potential starting point for adjustment */ if(tmp->iprt_bal) adjnd = tmp; if(add > tmp->iprt_ipa.ip_add){ if(!tmp->iprt_right){ tmp->iprt_right = node; node->iprt_bwd = tmp; break; } tmp = tmp->iprt_right; } else if(add < tmp->iprt_ipa.ip_add){ if(!tmp->iprt_left){ tmp->iprt_left = node; node->iprt_bwd = tmp; break; } tmp = tmp->iprt_left; } else return(0); } /* adjust balance factors, starting from next after adjnd. (adjnd adjusted later) */ if(add < adjnd->iprt_ipa.ip_add){ tmp = adjnd->iprt_left; a = -1; } else{ tmp = adjnd->iprt_right; a = 1; } r = tmp; while(tmp != node){ if(add < tmp->iprt_ipa.ip_add){ tmp->iprt_bal = -1; tmp = tmp->iprt_left; } else{ tmp->iprt_bal = 1; tmp = tmp->iprt_right; } } /* do we need to rebalance? */ if(!adjnd->iprt_bal){ /* tree 1 deeper, still balanced. only happens when adjnd is head */ adjnd->iprt_bal = a; } else if( adjnd->iprt_bal != a ){ /* tree is more balanced */ adjnd->iprt_bal = 0; } else{ /* whoops, out of balance, rebalance */ if( r->iprt_bal == a ){ /* right single rotate */ if( a == 1 ){ /* fwd ptrs */ adjnd->iprt_right = r->iprt_left; r->iprt_left = adjnd; adjnd->iprt_bal = r->iprt_bal = 0; if(adjnd != head){ ADJ_BLINK(adjnd,r); } else{ /* tree head has changed, must adjust link of trees */ if(adjnd->iprt_bwd){ adjnd->iprt_bwd->iprt_fwd = r; } else{ tbl[2*bin] = r; } if(adjnd->iprt_fwd){ adjnd->iprt_fwd->iprt_bwd = r; } else{ tbl[2*bin+1] = r; } r->iprt_fwd = adjnd->iprt_fwd; } /* iprt_bwd ptrs */ r->iprt_bwd = adjnd->iprt_bwd; adjnd->iprt_bwd = r; if(adjnd->iprt_right) adjnd->iprt_right->iprt_bwd = adjnd; } /* left single rotate */ else{ /* fwd ptrs */ adjnd->iprt_left = r->iprt_right; r->iprt_right = adjnd; adjnd->iprt_bal = r->iprt_bal = 0; if(adjnd != head){ ADJ_BLINK(adjnd,r); } else{ /* tree head has changed, must adjust link of trees */ if(adjnd->iprt_bwd){ adjnd->iprt_bwd->iprt_fwd = r; } else{ tbl[2*bin] = r; } if(adjnd->iprt_fwd){ adjnd->iprt_fwd->iprt_bwd = r; } else{ tbl[2*bin+1] = r; } r->iprt_fwd = adjnd->iprt_fwd; } /* back ptrs */ r->iprt_bwd = adjnd->iprt_bwd; adjnd->iprt_bwd = r; if(adjnd->iprt_left) adjnd->iprt_left->iprt_bwd = adjnd; } } else{ /* right double rotate */ if( a == 1){ /* fwd links */ tmp = r->iprt_left; r->iprt_left = tmp->iprt_right; tmp->iprt_right = r; adjnd->iprt_right = tmp->iprt_left; tmp->iprt_left = adjnd; if(tmp->iprt_bal == a){ adjnd->iprt_bal = -a; r->iprt_bal = 0; } else if(!tmp->iprt_bal){ adjnd->iprt_bal = 0; r->iprt_bal = 0; } else{ adjnd->iprt_bal = 0; r->iprt_bal = a; } tmp->iprt_bal = 0; if(adjnd != head){ ADJ_BLINK(adjnd,tmp); } else{ /* tree head has changed, must adjust link of trees */ if(adjnd->iprt_bwd){ adjnd->iprt_bwd->iprt_fwd = tmp; } else{ tbl[2*bin] = tmp; } if(adjnd->iprt_fwd){ adjnd->iprt_fwd->iprt_bwd = tmp; } else{ tbl[2*bin+1] = tmp; } tmp->iprt_fwd = adjnd->iprt_fwd; } /* back links */ tmp->iprt_bwd = adjnd->iprt_bwd; r->iprt_bwd = tmp; adjnd->iprt_bwd = tmp; if(adjnd->iprt_right) adjnd->iprt_right->iprt_bwd = adjnd; if(r->iprt_left) r->iprt_left->iprt_bwd = r; } else{ /* fwd links */ tmp = r->iprt_right; r->iprt_right = tmp->iprt_left; tmp->iprt_left = r; adjnd->iprt_left = tmp->iprt_right; tmp->iprt_right = adjnd; if(tmp->iprt_bal == a){ adjnd->iprt_bal = -a; r->iprt_bal = 0; } else if(!tmp->iprt_bal){ adjnd->iprt_bal = 0; r->iprt_bal = 0; } else{ adjnd->iprt_bal = 0; r->iprt_bal = a; } tmp->iprt_bal = 0; if(adjnd != head){ ADJ_BLINK(adjnd,tmp); } else{ /* tree head has changed, must adjust link of trees */ if(adjnd->iprt_bwd){ adjnd->iprt_bwd->iprt_fwd = tmp; } else{ tbl[2*bin] = tmp; } if(adjnd->iprt_fwd){ adjnd->iprt_fwd->iprt_bwd = tmp; } else{ tbl[2*bin+1] = tmp; } tmp->iprt_fwd = adjnd->iprt_fwd; } /* back links */ tmp->iprt_bwd = adjnd->iprt_bwd; r->iprt_bwd = tmp; adjnd->iprt_bwd = tmp; if(adjnd->iprt_left) adjnd->iprt_left->iprt_bwd = adjnd; if(r->iprt_right) r->iprt_right->iprt_bwd = r; } } } return(0);}static void ip_btdelete(iproute_ent *nd,iproute_ent *head,iproute_ent **tbl,int bin){ iproute_ent *tmp,*fwd,*x; iproute_ent troute; int lr,arht,alht,blht,brht; /* we can only remove from end of tree, so.. */ /* if have both left and right link, shuffle by finding the leftmost entry in the right path and exchanging. the resulting tree is out of order, but we dont care since the offending member (nd), which is now at the end, will be deleted. */ if(nd->iprt_left && nd->iprt_right){ tmp = nd->iprt_right; while(tmp->iprt_left){ tmp = tmp->iprt_left; } /* do swap places */ troute.iprt_right = tmp->iprt_right; troute.iprt_bwd = tmp->iprt_bwd; troute.iprt_bal = tmp->iprt_bal; tmp->iprt_bwd = nd->iprt_bwd; if(nd->iprt_right == tmp){ tmp->iprt_right = nd; nd->iprt_bwd = tmp; } else{ tmp->iprt_right = nd->iprt_right; nd->iprt_bwd = troute.iprt_bwd; } tmp->iprt_left = nd->iprt_left; tmp->iprt_fwd = nd->iprt_fwd; tmp->iprt_bal = nd->iprt_bal; nd->iprt_left = 0; nd->iprt_right = troute.iprt_right; nd->iprt_fwd = 0; nd->iprt_bal = troute.iprt_bal; /* now adjust all links pointing to these nodes. */ if(head == nd){ head = tmp; if(tmp->iprt_fwd){ tmp->iprt_fwd->iprt_bwd = tmp; } else{ tbl[2*bin+1] = tmp; } if(tmp->iprt_bwd){ tmp->iprt_bwd->iprt_fwd = tmp; } else{ tbl[2*bin] = tmp; } } else{ if(tmp->iprt_bwd->iprt_left == nd) tmp->iprt_bwd->iprt_left = tmp; else tmp->iprt_bwd->iprt_right = tmp; } tmp->iprt_left->iprt_bwd = tmp; tmp->iprt_right->iprt_bwd = tmp; if(nd->iprt_right) nd->iprt_right->iprt_bwd = nd; /* if nodes were not adjacent */ if(tmp->iprt_right != nd){ nd->iprt_bwd->iprt_left = nd; } } /* now delete a node which has at least one null link*/ if(!nd->iprt_left){ /* previous will now point to our right */ if(nd != head){ tmp = nd->iprt_bwd; if(nd->iprt_bwd->iprt_left == nd){ nd->iprt_bwd->iprt_left = nd->iprt_right; lr = +1; } else{ nd->iprt_bwd->iprt_right = nd->iprt_right; lr = -1; } if(nd->iprt_right) nd->iprt_right->iprt_bwd = nd->iprt_bwd; } else{ /* we know he has right link or never enter ip_btdelete */ head = nd->iprt_right; head->iprt_bwd = nd->iprt_bwd; if(head->iprt_bwd) head->iprt_bwd->iprt_fwd = head; else tbl[2*bin] = head; head->iprt_fwd = nd->iprt_fwd; if(head->iprt_fwd) head->iprt_fwd->iprt_bwd = head; else tbl[2*bin+1] = head; return; } } else{ /* previous will now point to our iprt_left */ if(nd != head){ tmp = nd->iprt_bwd; if(nd->iprt_bwd->iprt_right == nd){ nd->iprt_bwd->iprt_right = nd->iprt_left; lr = -1; } else{ nd->iprt_bwd->iprt_left = nd->iprt_left; lr = +1; } if(nd->iprt_left) nd->iprt_left->iprt_bwd = nd->iprt_bwd; } else{ /* we know he has left link or never enter ip_btdelete */ head = nd->iprt_left; head->iprt_bwd = nd->iprt_bwd; if(head->iprt_bwd) head->iprt_bwd->iprt_fwd = head; else tbl[2*bin] = head; head->iprt_fwd = nd->iprt_fwd; if(head->iprt_fwd) head->iprt_fwd->iprt_bwd = head; else tbl[2*bin+1] = head; return; } } /* work our way back up the tree, rebalancing as we go. start with the parent of the node we just deleted. here is the pertinent info we need: - we know that parent's tree has shrunk by one on the side nd was on, whether or not nd had a child. - we know nd's child tree, if it had one consisted of only a single child on one side, otherwise the tree was out of balance to begin with. */ while(tmp){ tmp->iprt_bal += lr; if(tmp->iprt_bal >1){ /* need to rebalance, 3 cases (and their mirror. all delete from a left. (see knuth pg 454) 1: a->right = b, alht = h, blht = h, brht = h+1 2: a->right = b, alht = h, blht = h+1, brht = h 3: a->right = b, alht = h, blht = h+1, brht = h+1 dgenerates to case 1, except new bal */ alht = getTreeHeight(tmp->iprt_left); blht = getTreeHeight(tmp->iprt_right->iprt_left); brht = getTreeHeight(tmp->iprt_right->iprt_right); if(alht != brht){ /* case 1/3 single rotate */ /* fwd ptrs */ fwd = tmp->iprt_right; tmp->iprt_right = fwd->iprt_left; fwd->iprt_left = tmp; if(tmp != head){ ADJ_BLINK(tmp,fwd); } else{ if(tmp->iprt_bwd) tmp->iprt_bwd->iprt_fwd = fwd; else tbl[2*bin] = fwd; if(tmp->iprt_fwd) tmp->iprt_fwd->iprt_bwd = fwd; else tbl[2*bin+1] = fwd; head = fwd; head->iprt_fwd = tmp->iprt_fwd; } /* back ptrs */ fwd->iprt_bwd = tmp->iprt_bwd; tmp->iprt_bwd = fwd; if(tmp->iprt_right) tmp->iprt_right->iprt_bwd = tmp; /* adjust balance */ if(blht != brht) fwd->iprt_bal = tmp->iprt_bal = 0; else{ tmp->iprt_bal = +1; fwd->iprt_bal = -1; } tmp = fwd; } else{ /* case 2 double rotate */ /* fwd links */ fwd = tmp->iprt_right; x = fwd->iprt_left; fwd->iprt_left = x->iprt_right; x->iprt_right = fwd; tmp->iprt_right = x->iprt_left; x->iprt_left = tmp; if(tmp != head){ ADJ_BLINK(tmp,x); } else{ if(tmp->iprt_bwd) tmp->iprt_bwd->iprt_fwd = x; else tbl[2*bin] = x; if(tmp->iprt_fwd) tmp->iprt_fwd->iprt_bwd = x; else tbl[2*bin+1] = x; head = x; head->iprt_fwd = tmp->iprt_fwd; } /* back links */ x->iprt_bwd = tmp->iprt_bwd; fwd->iprt_bwd = x; tmp->iprt_bwd = x; if(tmp->iprt_right) tmp->iprt_right->iprt_bwd = tmp; if(fwd->iprt_left) fwd->iprt_left->iprt_bwd = fwd; /* adjust balance count */ if(x->iprt_bal == 1){ tmp->iprt_bal = -1; fwd->iprt_bal = 0; } else if(!x->iprt_bal){ tmp->iprt_bal = 0; fwd->iprt_bal = 0; } else{ tmp->iprt_bal = 0; fwd->iprt_bal = +1; } x->iprt_bal = 0; tmp = x; } } else if(tmp->iprt_bal < -1){ /* mirror above */ arht = getTreeHeight(tmp->iprt_right); blht = getTreeHeight(tmp->iprt_left->iprt_left); brht = getTreeHeight(tmp->iprt_left->iprt_right); if(arht != blht){ /* case 1/3 single rotate */ /* fwd ptrs */ fwd = tmp->iprt_left; tmp->iprt_left = fwd->iprt_right; fwd->iprt_right = tmp; if(tmp != head){ ADJ_BLINK(tmp,fwd); } else{ if(tmp->iprt_bwd) tmp->iprt_bwd->iprt_fwd = fwd; else tbl[2*bin] = fwd; if(tmp->iprt_fwd) tmp->iprt_fwd->iprt_bwd = fwd; else tbl[2*bin+1] = fwd; head = fwd; head->iprt_fwd = tmp->iprt_fwd; } /* back ptrs */ fwd->iprt_bwd = tmp->iprt_bwd; tmp->iprt_bwd = fwd; if(tmp->iprt_left) tmp->iprt_left->iprt_bwd = tmp; /* adjust balance */ if(blht != brht) fwd->iprt_bal = tmp->iprt_bal = 0; else{ tmp->iprt_bal = -1; fwd->iprt_bal = +1; } tmp = fwd; } else{ /* case 2 double rotate */ /* fwd links */ fwd = tmp->iprt_left; x = fwd->iprt_right; fwd->iprt_right = x->iprt_left; x->iprt_left = fwd; tmp->iprt_left = x->iprt_right; x->iprt_right = tmp; if(tmp != head){ ADJ_BLINK(tmp,x); } else{ if(tmp->iprt_bwd) tmp->iprt_bwd->iprt_fwd = x; else tbl[2*bin] = x; if(tmp->iprt_fwd) tmp->iprt_fwd->iprt_bwd = x; else tbl[2*bin+1] = x; head = x; head->iprt_fwd = tmp->iprt_fwd; } /* back links */ x->iprt_bwd = tmp->iprt_bwd; fwd->iprt_bwd = x; tmp->iprt_bwd = x; if(tmp->iprt_left) tmp->iprt_left->iprt_bwd = tmp; if(fwd->iprt_right) fwd->iprt_right->iprt_bwd = fwd; /* adjust balance count */ if(x->iprt_bal == -1){ tmp->iprt_bal = +1; fwd->iprt_bal = 0; } else if(!x->iprt_bal){ tmp->iprt_bal = 0; fwd->iprt_bal = 0; } else{ tmp->iprt_bal = 0; fwd->iprt_bal = -1; } x->iprt_bal = 0; tmp = x; } } else{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?