Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 03ea79a

Browse files
committed
Implemented delete, depth, height and various private utility methods
1 parent 8a73eb8 commit 03ea79a

File tree

1 file changed

+141
-3
lines changed
  • Data Structures.playground/Pages/BinarySearchTree.xcplaygroundpage

1 file changed

+141
-3
lines changed

‎Data Structures.playground/Pages/BinarySearchTree.xcplaygroundpage/Contents.swift‎

Lines changed: 141 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,26 @@ class BinarySearchTree<T: Comparable> {
3838

3939
// MARK: - Methods
4040

41+
func height() -> Int {
42+
if leftChild == nil, rightChild == nil {
43+
return 0
44+
}
45+
return 1 + max(leftChild?.height() ?? 0, rightChild?.height() ?? 0)
46+
}
47+
48+
func depth() -> Int {
49+
guard var parentNode = parent else {
50+
return 0
51+
}
52+
53+
var depth = 1
54+
while let grandParentNode = parentNode.parent {
55+
depth += 1
56+
parentNode = grandParentNode
57+
}
58+
return depth
59+
}
60+
4161
/// Inorder binary tree traversal simply means a traversal with the following rule: left value < node value < right value
4262
/// As a result we get sorted results from the smallest value to the greathest (according to the comparator patter, since each element must conform to Comparable protocol)
4363
/// - node: is a BinarySearchTreeNode? which you would like to traverse
@@ -107,6 +127,56 @@ class BinarySearchTree<T: Comparable> {
107127
addNode(value: value)
108128
}
109129

130+
func delete() {
131+
if let left = leftChild {
132+
if let _ = rightChild {
133+
// 2 children
134+
exchangeWithSuccessor(node: self)
135+
} else {
136+
// 1 child - left
137+
attachParent(to: left, for: self)
138+
}
139+
} else if let right = rightChild {
140+
// 1 child - right
141+
attachParent(to: right, for: self)
142+
} else {
143+
// connet the node to the parent node
144+
attachParent(to: nil, for: self)
145+
}
146+
parent = nil
147+
leftChild = nil
148+
rightChild = nil
149+
}
150+
151+
func deleteNode(for value: T) -> Bool {
152+
guard let nodeToDelete = search(value: value) else {
153+
return false
154+
}
155+
156+
if let left = nodeToDelete.leftChild {
157+
if let _ = nodeToDelete.rightChild {
158+
// 2 children
159+
exchangeWithSuccessor(node: nodeToDelete)
160+
} else {
161+
// 1 child - left
162+
attachParent(to: left, for: nodeToDelete)
163+
}
164+
} else if let right = nodeToDelete.rightChild {
165+
// 1 child - right
166+
attachParent(to: right, for: nodeToDelete)
167+
} else {
168+
// connet the node to the parent node
169+
attachParent(to: nil, for: nodeToDelete)
170+
}
171+
nodeToDelete.parent = nil
172+
nodeToDelete.leftChild = nil
173+
nodeToDelete.rightChild = nil
174+
175+
return true
176+
}
177+
178+
// MARK: - Private methods
179+
110180
private func addNode(value: T) {
111181
if value < self.value {
112182
if let leftChild = self.leftChild {
@@ -127,13 +197,76 @@ class BinarySearchTree<T: Comparable> {
127197
}
128198
}
129199

130-
// MARK: - Private methods
131-
132200
private func createNewNode(with value: T) -> BinarySearchTree {
133201
let newNode = BinarySearchTree(value: value)
134202
return newNode
135203
}
136204

205+
private func attachParent(to child: BinarySearchTree?, for node: BinarySearchTree) {
206+
guard let parent = node.parent else {
207+
child?.parent = node.parent
208+
return
209+
}
210+
if parent.leftChild === node {
211+
parent.leftChild = child
212+
child?.parent = parent
213+
} else if parent.rightChild === node {
214+
parent.rightChild = child
215+
child?.parent = parent
216+
}
217+
}
218+
219+
private func exchangeWithSuccessor(node: BinarySearchTree) {
220+
guard let right = node.rightChild, let left = node.leftChild else {
221+
return
222+
}
223+
let successor = right.minNode()
224+
successor.delete()
225+
226+
successor.leftChild = left
227+
left.parent = successor
228+
229+
if right !== successor {
230+
successor.rightChild = right
231+
right.parent = successor
232+
} else {
233+
successor.rightChild = nil
234+
}
235+
attachParent(to: successor, for: node)
236+
}
237+
238+
private func minValue() -> T {
239+
if let left = leftChild {
240+
return left.minValue()
241+
} else {
242+
return value
243+
}
244+
}
245+
246+
private func maxValue() -> T {
247+
if let right = rightChild {
248+
return right.maxValue()
249+
} else {
250+
return value
251+
}
252+
}
253+
254+
private func minNode() -> BinarySearchTree {
255+
if let left = leftChild {
256+
return left.minNode()
257+
} else {
258+
return self
259+
}
260+
}
261+
262+
private func maxNode() -> BinarySearchTree {
263+
if let right = rightChild {
264+
return right.maxNode()
265+
} else {
266+
return self
267+
}
268+
}
269+
137270
}
138271

139272
extension BinarySearchTree: CustomStringConvertible, CustomDebugStringConvertible {
@@ -185,6 +318,11 @@ try! rootNode.insertNode(for: 4)
185318

186319
print(rootNode)
187320

321+
let wasDeleted = rootNode.deleteNode(for: 5)
322+
print("wasDeleted ", wasDeleted)
323+
324+
print(rootNode)
325+
188326
var assembledElements = [Int]()
189327
BinarySearchTree.traverseInorder(from: rootNode, handler: { value in
190328
assembledElements += [value]
@@ -205,7 +343,7 @@ print(postorderElements)
205343

206344
// Search the number
207345
let node = rootNode.search(value: 5)
208-
print(node)
346+
print(nodeasAny)
209347

210348
// Great! Now let's change the type to String and do the same:
211349

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /