You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Binary Search Tree/README.markdown
+29-103
Original file line number
Diff line number
Diff line change
@@ -69,21 +69,14 @@ If you traverse a binary search tree in-order, it looks at all the nodes as if t
69
69
70
70
## Deleting nodes
71
71
72
-
Removing nodes is kinda tricky. It is easy to remove a leaf node, you just disconnect it from its parent:
73
-
74
-

75
-
76
-
If the node to remove has only one child, we can link that child to the parent node. So we just pull the node out:
77
-
78
-

79
-
80
-
The gnarly part is when the node to remove has two children. To keep the tree properly sorted, we must replace this node by the smallest child that is larger than the node:
72
+
Removing nodes is also easy. After removing a node, we replace the node with either its biggest child on the left or its smallest child on the right. That way the tree is still sorted after the removal. In following example, 10 is removed and replaced with either 9 (Figure 2), or 11 (Figure 3).
81
73
82
74

83
75
84
-
This is always the leftmost descendant in the right subtree. It requires an additional search of at most **O(h)** to find this child.
76
+
Note the replacement needs to happen when the node has at least one child. If it has no child, you just disconnect it from its parent:
77
+
78
+

85
79
86
-
Most of the other code involving binary search trees is fairly straightforward (if you understand recursion) but deleting nodes is a bit of a headscratcher.
87
80
88
81
## The code (solution 1)
89
82
@@ -158,23 +151,19 @@ A tree node by itself is pretty useless, so here is how you would add new nodes
@@ -396,7 +385,7 @@ You've seen that deleting nodes can be tricky. We can make the code much more re
396
385
397
386
Making changes to the tree involves changing a bunch of `parent` and `left` and `right` pointers. This function helps with that. It takes the parent of the current node -- that is `self` -- and connects it to another node. Usually that other node will be one of the children of `self`.
398
387
399
-
We also need a function that returns the leftmost descendent of a node:
388
+
We also need a function that returns the minimum and maximum of a node:
400
389
401
390
```swift
402
391
publicfuncminimum() -> BinarySearchTree {
@@ -406,112 +395,49 @@ We also need a function that returns the leftmost descendent of a node:
406
395
}
407
396
return node
408
397
}
409
-
```
410
-
411
-
To see how this works, take the following tree:
412
-
413
-

414
-
415
-
For example, if we look at node `10`, its leftmost descendent is `7`. We get there by following all the `left` pointers until there are no more left children to look at. The leftmost descendent of the root node `6` is `1`. Therefore, `1` is the minimum value in the entire tree.
416
-
417
-
We won't need it for deleting, but for completeness' sake, here is the opposite of `minimum()`:
418
-
419
-
```swift
398
+
420
399
publicfuncmaximum() -> BinarySearchTree {
421
400
var node =self
422
401
whilecaselet next?= node.right {
423
402
node = next
424
403
}
425
404
return node
426
405
}
427
-
```
428
406
429
-
It returns the rightmost descendent of the node. We find it by following `right` pointers until we get to the end. In the above example, the rightmost descendent of node `2` is `5`. The maximum value in the entire tree is `11`, because that is the rightmost descendent of the root node `6`.
407
+
```
430
408
431
-
Finally, we can write the code that removes a node from the tree:
// Place the replacement on current node's position
428
+
replacement?.right= right;
429
+
replacement?.left= left;
430
+
reconnectParentTo(node:replacement);
431
+
432
+
// The current node is no longer part of the tree, so clean it up.
451
433
parent =nil
452
434
left =nil
453
435
right =nil
454
-
455
-
return replacement
456
-
}
457
-
```
458
-
459
-
It doesn't look so scary after all. ;-) There are four situations to handle:
460
-
461
-
1. This node has two children.
462
-
2. This node only has a left child. The left child replaces the node.
463
-
3. This node only has a right child. The right child replaces the node.
464
-
4. This node has no children. We just disconnect it from its parent.
465
-
466
-
First, we determine which node will replace the one we're removing and then we call `reconnectParentToNode()` to change the `left`, `right`, and `parent` pointers to make that happen. Since the current node is no longer part of the tree, we clean it up by setting its pointers to `nil`. Finally, we return the node that has replaced the removed one (or `nil` if this was a leaf node).
467
-
468
-
The only tricky situation here is `// 1` and that logic has its own helper method:
If the node to remove has two children, it must be replaced by the smallest child that is larger than this node's value. That always happens to be the leftmost descendent of the right child, i.e. `right.minimum()`. We take that node out of its original position in the tree and put it into the place of the node we're removing.
490
-
491
-
Try it out:
492
-
493
-
```swift
494
-
iflet node2 = tree.search(2) {
495
-
print(tree) // before
496
-
node2.remove()
497
-
print(tree) // after
498
-
}
499
-
```
500
-
501
-
First you find the node that you want to remove with `search()` and then you call `remove()` on that object. Before the removal, the tree printed like this:
502
-
503
-
((1) <- 2 -> (5)) <- 6 -> ((9) <- 10)
504
-
505
-
But after `remove()` you get:
506
-
507
-
((1) <- 5) <- 6 -> ((9) <- 10)
508
-
509
-
As you can see, node `5` has taken the place of `2`.
510
-
511
-
> **Note:** What would happen if you deleted the root node? In that case, `remove()` tells you which node has become the new root. Try it out: call `tree.remove()` and see what happens.
512
-
513
-
Like most binary search tree operations, removing a node runs in **O(h)** time, where **h** is the height of the tree.
514
-
515
441
### Depth and height
516
442
517
443
Recall that the height of a node is the distance to its lowest leaf. We can calculate that with the following function:
0 commit comments