public bool Remove(IAvlNode node) { if (node == null) { throw new ArgumentNullException(nameof(node)); } var left = node.Left; var right = node.Right; var parent = node.Parent; if (left == null) { if (right == null) { if (node == Root) { Clear(); return(true); } if (parent == null) { throw new Exception(); } if (parent.Left == node) { parent.Left = null; DeleteBalanceTree(parent, 1); } else { parent.Right = null; DeleteBalanceTree(parent, -1); } } else { if (node == Root) { node.Right.Parent = null; Root = (T)node.Right; return(true); } node.Right.Parent = node.Parent; if (parent.Left == node) { parent.Left = node.Right; DeleteBalanceTree(parent, 1); } else { parent.Right = node.Right; DeleteBalanceTree(parent, -1); } } } else if (right == null) { if (node == Root) { node.Left.Parent = null; Root = (T)node.Left; return(true); } node.Left.Parent = node.Parent; if (parent.Left == node) { parent.Left = node.Left; DeleteBalanceTree(parent, 1); } else { parent.Right = node.Left; DeleteBalanceTree(parent, -1); } } else { // no (half-)leaf IAvlNode successor; if (node.Balance > -1) { successor = node.AvlGetNextNode(); } else { successor = node.AvlGetPrevNode(); } SwitchNodes(node, successor); successor.UpdateAugmentedData(); return(Remove(node)); } if (parent != null) { parent.UpdateAugmentedData(); } Count--; OnNodeRemoved(new TreeNodeEventArgs((T)node)); return(true); }