Skip to content

Commit 942e3b1

Browse files
Bo QianBo Qian
Bo Qian
authored and
Bo Qian
committed
Simplified the remove(). I feel the new implementation is more elegant and conceptually more straightforward.
1 parent ca35d57 commit 942e3b1

File tree

1 file changed

+34
-63
lines changed

1 file changed

+34
-63
lines changed

Binary Search Tree/Solution 1/BinarySearchTree.playground/Sources/BinarySearchTree.swift

+34-63
Original file line numberDiff line numberDiff line change
@@ -106,58 +106,30 @@ extension BinarySearchTree {
106106
*/
107107
@discardableResult public func remove() -> BinarySearchTree? {
108108
let replacement: BinarySearchTree?
109-
109+
110+
// Replacement for current node can be either biggest one on the left or
111+
// smallest one on the right, whichever is not nil
110112
if let left = left {
111-
if let right = right {
112-
replacement = removeNodeWithTwoChildren(left, right)
113-
} else {
114-
// This node only has a left child. The left child replaces the node.
115-
replacement = left
116-
}
113+
replacement = left.maximum()
117114
} else if let right = right {
118-
// This node only has a right child. The right child replaces the node.
119-
replacement = right
115+
replacement = right.minimum()
120116
} else {
121-
// This node has no children. We just disconnect it from its parent.
122-
replacement = nil
117+
replacement = nil;
123118
}
124-
125-
reconnectParentTo(node: replacement)
126-
119+
120+
replacement?.remove();
121+
122+
// Place the replacement on current node's position
123+
replacement?.right = right;
124+
replacement?.left = left;
125+
reconnectParentTo(node:replacement);
126+
127127
// The current node is no longer part of the tree, so clean it up.
128128
parent = nil
129129
left = nil
130130
right = nil
131-
132-
return replacement
133-
}
134-
135-
private func removeNodeWithTwoChildren(_ left: BinarySearchTree, _ right: BinarySearchTree) -> BinarySearchTree {
136-
// This node has two children. It must be replaced by the smallest
137-
// child that is larger than this node's value, which is the leftmost
138-
// descendent of the right child.
139-
let successor = right.minimum()
140-
141-
// If this in-order successor has a right child of its own (it cannot
142-
// have a left child by definition), then that must take its place.
143-
successor.remove()
144-
145-
// Connect our left child with the new node.
146-
successor.left = left
147-
left.parent = successor
148-
149-
// Connect our right child with the new node. If the right child does
150-
// not have any left children of its own, then the in-order successor
151-
// *is* the right child.
152-
if right !== successor {
153-
successor.right = right
154-
right.parent = successor
155-
} else {
156-
successor.right = nil
157-
}
158-
159-
// And finally, connect the successor node to our parent.
160-
return successor
131+
132+
return replacement;
161133
}
162134

163135
private func reconnectParentTo(node: BinarySearchTree?) {
@@ -350,24 +322,23 @@ extension BinarySearchTree: CustomStringConvertible {
350322
}
351323
return s
352324
}
353-
}
354-
355-
extension BinarySearchTree: CustomDebugStringConvertible {
356-
public var debugDescription: String {
357-
var s = "value: \(value)"
358-
if let parent = parent {
359-
s += ", parent: \(parent.value)"
360-
}
361-
if let left = left {
362-
s += ", left = [" + left.debugDescription + "]"
363-
}
364-
if let right = right {
365-
s += ", right = [" + right.debugDescription + "]"
366-
}
367-
return s
368-
}
325+
326+
public func toArray() -> [T] {
327+
return map { $0 }
328+
}
369329

370-
public func toArray() -> [T] {
371-
return map { $0 }
372-
}
373330
}
331+
332+
//extension BinarySearchTree: CustomDebugStringConvertible {
333+
// public var debugDescription: String {
334+
// var s = ""
335+
// if let left = left {
336+
// s += "(\(left.description)) <- "
337+
// }
338+
// s += "\(value)"
339+
// if let right = right {
340+
// s += " -> (\(right.description))"
341+
// }
342+
// return s
343+
// }
344+
//}

0 commit comments

Comments
 (0)