// 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;
}
Beispiel #2
0
/*
 * 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);
	}
}
Beispiel #3
0
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;
}
Beispiel #5
0
void deleteTrie(Trie trie) {
	nodeDelete(trie->dummy);
	free(trie);
}