// Remove key from pp. Returns true if pp needs rebalancing. false if not bool TreeSetImpl::nodeDelete(TreeSetNode *&pp, const void *key) { TreeSetNode *p = pp; if(p == NULL) { return false; // key not found } const int c = m_comparator->cmp(p->m_key, key); if(c > 0) { // pp.key > key. Continue search in left subtree if(nodeDelete(p->m_left, key)) { return balanceL(pp); } else { return false; } } if(c < 0) { // pp.key < key. Continue search in right subtree if(nodeDelete(p->m_right, key)) { return balanceR(pp); } else { return false; } } bool result = false; if(p->m_right == NULL) { pp = p->m_left; result = true; } else if(p->m_left == NULL) { pp = p->m_right; result = true; } else { m_deleteHelper = p; if(nodeDel(p->m_left)) { result = balanceL(pp); } p = m_deleteHelper; } deleteNode(p); m_size--; m_updateCount++; return result; }
/* * Trie deletion has 3 cases * * Case 1: The word is a separate branch in the tree and it doesn't have * any other children. Simply delete the starting node. * Case 2: The word contains suffices. Only remove the "word" marker * Case 3: The reverse of Case 2. The word is a suffix. Delete only the * suffix * * This only replaces the deleted node with NULL and then calling the * sortChild() function and then realloc() * * realloc() only fails if size == 0 or if the block cannot be reallocated */ void deleteWord(Trie trie, char *str) { Node current = trie->dummy, temp = NULL; int i, tmp; if(!searchWord(trie, str)) return; /* Test for case 1*/ if(testCase(trie, str, case1)) { /* Simply remove the node */ i = findChildID(current, str[0]); nodeDelete(current->child[i]); resizeChildren(current); } else if(testCase(trie, str, case2)) { /* Test for case 2 */ /* No real deletion occurs here, the nodes would * still be there, but it makes the word unsearchable */ for(i = 0; i < strlen(str); i++) { current = findChild(current, str[i]); } current->endMarker = false; } else if(testCase(trie, str, case3)) { /* Test for case 3 */ /* Traverse the word and keep track on which node * had children > 1, then find the next matching node * and delete it */ temp = trie->dummy; for(i = 0; i < strlen(str); i++) { temp = findChild(temp, str[i]); if(temp->children > 1) { current = temp; tmp = i+1; } } i = findChildID(current, str[tmp]); nodeDelete(current->child[i]); resizeChildren(current); } }
Node* AvlTree::nodeDelete(Node *rootNode, int data){ if (rootNode == NULL){ return NULL; } if (data == rootNode->data){ delete rootNode; return NULL; } if (data < rootNode -> data){ rootNode -> left = this -> nodeDelete(rootNode->left, data); rootNode -> height = MAX(Height(rootNode->left) , Height(rootNode -> right)) + 1; int rightHeight = 0; if (rootNode -> right != NULL){ rightHeight = rootNode -> right -> height; } if (Height(rootNode -> left) >= rightHeight + 2){ if (data < rootNode -> left -> data){ rootNode = LL(rootNode); }else{ rootNode = LR(rootNode); } } }else{ if (data > rootNode -> data){ rootNode -> right = nodeDelete(rootNode -> right, data); rootNode -> height = 1 + MAX(Height(rootNode -> left) , Height(rootNode -> right)); int leftHeight = 0; if (rootNode -> left != NULL){ leftHeight = rootNode -> left -> height; } if (Height(rootNode -> right) >= leftHeight + 2){ if (data > rootNode -> right -> data){ rootNode = RR(rootNode); }else{ rootNode = RL(rootNode); } } } } rootNode -> height = MAX(Height(rootNode -> left) , Height(rootNode -> right)) + 1; return rootNode; }
bool TreeSetImpl::remove(const void *key) { const size_t size = m_size; nodeDelete(m_root, key); return size != m_size; }
void deleteTrie(Trie trie) { nodeDelete(trie->dummy); free(trie); }