确保从根到树叶节点的每条路径都具有相同数量的黑色节点 ( C )

问题描述

我正在为大学目的实施红黑树,但我坚持从根到叶的每条路径都应具有相同数量的黑色节点。 我已经插入了所有需要的函数fixup,rotation,insertion...但我不知道如何处理这个函数。我在想:

void checkNuberBlackNodes(struct node* root) {
    if( numberBlackNodes(root->right) > numberBlackNodes(root->left) {
         leftRotate(root);
         colorize(root);
    }
    else if( numberBlackNodes(root->right) < numberBlackNodes(root->left) {
         rightRotate(root);
         colorize(root);
    }
    else return; //no violation,same number of black nodes
}

这个想法是insert一个节点,fix up违规,然后checkNumberBlackNodes插入的新节点(或从根)。 我不知道如何处理这个过程,所有以前的功能都很容易实现这是......我不知道我该如何开始。 编辑:我有一个新想法:

void checkNuberBlackNodes(struct node* root) {
  int diff = height(root->right) - height(root->left);
  if ( diff >=2 ) //if the tree is too deep
  {
     leftRotate(root->right);
     checkNuberBlackNodes(root->right);
     return;
  }
  else if ( diff <= -2 ) //specular case
  { 
     rightRotate(root->left);
     checkNuberBlackNodes(root->left);
     return;
  }
  else if( blackHeight(root->right) > blackHeight(root->left) {
     colorize(root->right);
     checkNuberBlackNodes(root->right);
     return;
  }
else if( blackHeight(root->right) < blackHeight(root->left) {
     colorize(root->left);
     checkNuberBlackNodes(root->left);
     return;
  }
else return; //No violation
}

blackHeight 是从节点到叶子的那条路径中黑色节点的数量

解决方法

如果在红黑树中插入一个新节点,该节点最后总是一个叶节点。 而且总是红色。

一般

(1) 插入一个节点可能会违反“没有连续的红色节点”规则,修正将在根的方向上。最多需要 2 次旋转和 3 * O(h/2) 次重新着色,其中 h 是树的高度。如果插入节点的父节点为黑色,则不需要修复。

(2) 删除一个节点可能会违反“从根向下每条路径的黑色节点数都相同”规则。同样,修复发生在 root 上。最多需要 3 次旋转和 O(h) 重新着色,其中 h 是树的高度。

如果要删除的节点是没有子节点的根节点,则删除它。

如果要删除的Node有两个孩子,找到直接的后继(右孩子然后一直向左),交换Node和后继Node(但保留节点的原始颜色)。后继节点将始终是 0 子节点或 1 子节点。 现在你需要删除原来的 Node 但在后继的位置。您将转到接下来的两个案例。

如果删除的节点是叶子节点并且是红色的,不需要修复,删除节点

如果要删除的节点只有一个子节点,它是黑色的,子节点是红色的,删除节点,用子节点替换节点,将子节点重新着色为黑色。

那么这留下了什么? 它留下一个黑色节点,即叶节点,没有子节点,困难的情况。 删除这将违反“从根到每条路径的黑色节点数都相同”规则。

删除节点后,父节点现在在树的一侧有黑色路径计数错误。基本上删除是一个双管齐下的策略:

a) 您检查父节点、同级节点和同级子节点以查看是否有红色。如果是,你可以使用旋转和重新着色来改变它,所以被删除一侧的黑洞被重新填充,修复树。 b) 如果所有节点(或 NULL 节点)都是黑色的,那么你将兄弟节点设为红色,父节点现在被认为是修复树的点。你使树的两边都变得同样糟糕,现在修复点高了 1 级。您返回到步骤 a),因为“父母”、“兄弟姐妹”和“兄弟姐妹”有了新的定义。 c) 可能有一棵全黑的红黑树。如果到达根节点并且没有遇到红色节点会发生什么?然后它现在是一棵红黑树。有效地,变化的兄弟姐妹在每条树路径中引入了 1 个红色节点,将黑树的高度均匀地降低了 1。