删除二叉搜索树某个节点,分为三种情况,度为0的,度为1的,度为2的。
//根据元素删除节点
- (void)removeElement:(NSInteger)element{
[self removeNode:[self node:element]];
}
//根据节点删除节点
- (void)removeNode:(Node *)node{
if (node == nil) {
return;
}
self.size--;
if ([node hasTwoChildren]) { //有左右节点
//找到后继节点
Node *s = [self successorNode:node];
//用后继节点的值覆盖本身节点
node.element = s.element;
//保存该后继节点局部值以便外界删除操作
node = s;
}
//开始删除节点,程序能执行到这儿,节点度必然为0或1
//保存节点的子节点(此处如果度为0,那么replacement必然是nil了,所以不用单独获取度为0的子节点)
Node *replacement = node.left != nil ? node.left : node.right;
if (replacement != nil) { //度为1的节点
//更改子节点的parent
replacement.parent = node.parent;
//更改node节点的parent节点的指向
if (node.parent == nil) { //此处是度为1的节点,且是根节点
self.root = replacement;
}else if (node == node.parent.left) {
node.parent.left = replacement;
}else if (node == node.parent.right){
node.parent.right = replacement;
}
}else { //度为0的节点
if (node.parent == nil) { //此处是度为0的叶子节点,且是根节点
self.root = nil;
}else {//度为0的节点,但不是根节点
if (node == node.parent.left) { //叶子节点为父节点的左节点
node.parent.left = nil;
}else if (node == node.parent.right){ //叶子节点为父节点的右节点
node.parent.right = nil;
}
}
}
}
//根据元素返回节点
-(Node *)node:(NSInteger)element{
Node *node = self.root;
while (node != nil) {
NSInteger cmp = element - node.element;
if (cmp == 0 ) {
return node;
}else if (cmp > 0){
node = node.right;
}else {
node = node.left;
}
}
return nil;
}