/** * @brief AVL tree delete one node. This method is to find its front data child, * means its first left-right child to cover its data value, and replace to * remove the child node. The verbose analysis is the following. * if pT has single child or no, then remove pT and attach its child to its * parent, now his parent bf --, and require rebalance it. * elseif pT has two child, find the front data child, means its first left-right * child, and copy the data in pT, and begin to remove this node named Y. As we * know Y has no child or single left child, so we can attach the child to Y's * parent. And then require rebalance from Y's parent to pT. * May be the Y should split 2 situation: * 1. the Y is the pT's lchild. * 2. the Y is the pT's lchild's grand right son. * * @param pT tree quote point. * @param plower output tree becomes lower or not. */ PRIVATE void _avl_deletenode(TREE* pT, int* plower) { if (NULL == (*pT)->lchild) { NODE* Y = (*pT); (*pT) = (*pT)->rchild; (*plower) = 1; free(Y); } else if (NULL == (*pT)->rchild) { NODE* Y = (*pT); (*pT) = (*pT)->lchild; (*plower) = 1; free(Y); } else { // (*pT)->lchild and (*pT)->rchild are all not null. NODE* Y = (*pT)->lchild; if (NULL == Y->rchild) { ELEMENT_COPY((*pT)->data, Y->data); (*pT)->lchild = Y->lchild; (*plower) = 1; free(Y); _avl_left_lower_rebalance(pT, plower); } else { // NULL != Y->rchild AVLTREE_STACK* TS = NULL; tree_stack_push(&TS, &((*pT)->lchild)); while (Y->rchild) { if (Y->rchild->rchild) { tree_stack_push(&TS, &(Y->rchild)); } Y = Y->rchild; } /// copy data to pT node and delete Y node ELEMENT_COPY((*pT)->data, Y->data); TREE* YF = tree_stack_front(&TS); (*YF)->rchild = Y->lchild; (*plower) = 1; free(Y); // pop all parent line and right lower rabalance while (NULL != (YF = tree_stack_pop(&TS))) { if (0 == (*plower)) { continue; } _avl_right_lower_rebalance(YF, plower); } // finally do left lower rebalance if lower from left subtree if (1 == (*plower)) { _avl_left_lower_rebalance(pT, plower); } } } }
static int tree_item_circular(tree_item_t *item) { if ( item == NULL ) return 0; if ( tree_object_circular(item->object) ) { tree_stack_push(item->parent_tree, item->object); return 1; } return 0; }