/** * \file * * \author Georg Hopp * * \copyright * Copyright © 2012 Georg Hopp * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "trbase.h" #include "tr/tree.h" void * TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp) { TR_Tree node = *this; TR_Tree del_node; int found; void * data; TR_TREE_FIND(node, search, found, comp); /* * nothing was found...return NULL to indicate this. */ if (found != 0) { return NULL; } /* * we found an element, store its data pointer as we are * up to delete it. */ data = node->data; /* * now remove the element. */ /* * if we have two children replace data with the one from * out inOrderSuccessor and remove the inOrderSuccessor. */ if (NULL != TR_TREE_LEFT(node) && NULL != TR_TREE_RIGHT(node)) { TR_Tree successor; TR_TREE_INORDER_SUCC(node, successor); node->data = successor->data; node = successor; } { TR_Tree child = TR_TREE_CHILD(node); /* * if we still have one child replace ourself with it. */ TR_TREE_REPLACE_NODE(this, node, child); /* * and finally delete the node...and prepare ourselfs * for rebalancing. */ if (rbBlack == node->color) { if (NULL != child && rbRed == child->color) { child->color = rbBlack; TR_delete(node); return data; } else { del_node = node; if (NULL != child) { node = child; } else { node->color = rbBlack; node->left = NULL; node->right = NULL; } } } else { TR_delete(node); return data; } } /* * now comes rebalancing...note that if we came to this point * the node is still not deleted. * This is because I am not sure if it is needed during the * rebalancing process...(this does not make much sense, but * to be honest I don't know now.) */ { TR_Tree sibling = TR_TREE_SIBLING(node); TR_TREE_BALANCE_DELETE(this, node, sibling); } TR_delete(del_node); return data; } // vim: set ts=4 sw=4: