Esempio n. 1
0
void RBRemoveAll(struct RBTree* _Tree, void(*_Callback)(void*)) {
	struct RBItrStack _ItrStack[_Tree->Size];
	int i = 0;

	memset(_ItrStack, 0, sizeof(struct RBItrStack*) * _Tree->Size);
	RBDepthFirst(_Tree->Table, _ItrStack);
	for(i = 0; i < _Tree->Size; ++i)
		_Callback(_ItrStack[i].Node->Data);
	while(_Tree->Size > 0) {
		RBDeleteNode(_Tree, _Tree->Table);
	}
}
Esempio n. 2
0
void RBIterate(struct RBTree* _Tree, int(*_Callback)(void*)) {
	int i = 0;
	int j = 0;
	struct RBItrStack _Stack[_Tree->Size];
	struct RBItrStack _DeleteStack[_Tree->Size];

	if(_Tree->Table == NULL)
		return;
	memset(_Stack, 0, sizeof(struct RBItrStack*) * _Tree->Size);
	memset(_DeleteStack, 0, sizeof(struct RBItrStack*) * _Tree->Size);
	RBDepthFirst(_Tree->Table, _Stack);
	for(i = 0; i < _Tree->Size; ++i) {
		if(_Callback(_Stack[i].Node->Data) != 0)
			_DeleteStack[j] = _Stack[i];
	}
	for(i = 0; i < j; ++i)
		RBDeleteNode(_Tree, _DeleteStack[i].Node);
}
Esempio n. 3
0
void RBDelete(RBTree* tree, int key){
  RBNode* current = tree->root;
  while(current != tree->nil){
    if(key == current->key){
      break;
    }
    if(key < current->key){
      current = current->left;
    }else{
      current = current->right;
    }
  }

  if(current == tree->nil){
    return;
  }

  RBNode* replace = tree->nil;
  if(current->left == tree->nil && current->right == tree->nil){
    replace = current;
  }else if(current->left != tree->nil){
    replace = current->left;
    while(replace->right != tree->nil){
      replace = replace->right;
    }
  }else{
    replace = current->right;
    while(replace->left != tree->nil){
      replace = replace->left;
    }
  }

  current->key = replace->key;
  current->value = replace->value;

  RBDeleteNode(tree, replace);
}
Esempio n. 4
0
void RBClear(struct RBTree* _Tree) {
	while(_Tree->Size > 0) {
		RBDeleteNode(_Tree, _Tree->Table);
	}
}
Esempio n. 5
0
void RBDelete(struct RBTree* _Tree, void* _Data) {
	RBDeleteNode(_Tree, RBSearchNode(_Tree, _Data));
}
Esempio n. 6
0
void RBDeleteNode(RBTree* tree, RBNode* node){

  RBNode* child = node->left == tree->nil ? node->right : node->left;

  //node is root, and have no child at all
  if(child == tree->nil && node->isBlack){
    free(node);
    tree->root = tree->nil;
    return;
  }

  replace_node(tree, node, child);

  //if node is red, replace and free will just work
  if(node->isBlack){
    if(!child->isBlack){
      child->isBlack = true;
      free(node);  
      if(node == tree->root){
        tree->root = child;
      }
      return;
    }else{
      //node will never be root, because child is black, and exactly one child exists
      //so node->parent will never be tree->nil
      RBNode* sibling = node == node->parent->left ? node->parent->right : node->parent->left;
      if(!sibling->isBlack){
        node->parent->isBlack = false;
        sibling->isBlack = true;
        if(node == node->parent->left){
          leftRotate(tree, node->parent);
        }else{
          rightRotate(tree, node->parent);
        }
      }else{
        if(node->parent->isBlack && sibling->left->isBlack && sibling->right->isBlack){
          sibling->isBlack = false;
          RBDeleteNode(tree, node->parent);
        }else if(!node->parent->isBlack && sibling->left->isBlack && sibling->right->isBlack){
          sibling->isBlack = false;
          node->parent->isBlack = true;
        }else if(node == node->parent->left && sibling->right->isBlack && !sibling->left->isBlack){
          sibling->isBlack = false;
          sibling->left->isBlack = true;
          rightRotate(tree, sibling);
        }else if(node == node->parent->right && sibling->left->isBlack && !sibling->right->isBlack){
          sibling->isBlack = false;
          sibling->right->isBlack = true;
          leftRotate(tree, sibling);
        }else{
          sibling->isBlack = node->parent->isBlack;
          node->parent->isBlack = true;
          if(node == node->parent->left){
            sibling->right->isBlack = true;
            leftRotate(tree, node->parent);
          }else{
            sibling->left->isBlack = true;
            rightRotate(tree, node->parent);
          }
        }
      }
    }
  }

  free(node);
}