@@ -516,35 +516,34 @@ internal func _siftDown<C: MutableCollection & RandomAccessCollection>(
516
516
subRange range: Range < C . Index > ,
517
517
by areInIncreasingOrder: ( C . Element , C . Element ) throws -> Bool
518
518
) rethrows {
519
-
520
- let countToIndex = elements. distance ( from: range. lowerBound, to: index )
521
- let countFromIndex = elements. distance ( from: index , to: range. upperBound)
522
- // Check if left child is within bounds. If not, return , because there are
519
+ var i = index
520
+ var countToIndex = elements. distance ( from: range. lowerBound, to: i )
521
+ var countFromIndex = elements. distance ( from: i , to: range. upperBound)
522
+ // Check if left child is within bounds. If not, stop iterating , because there are
523
523
// no children of the given node in the heap.
524
- if countToIndex + 1 >= countFromIndex {
525
- return
526
- }
527
- let left = elements. index ( index, offsetBy: countToIndex + 1 )
528
- var largest = index
529
- if ( try areInIncreasingOrder ( elements [ largest] , elements [ left] ) ) {
530
- largest = left
531
- }
532
- // Check if right child is also within bounds before trying to examine it.
533
- if countToIndex + 2 < countFromIndex {
534
- let right = elements. index ( after: left)
535
- if ( try areInIncreasingOrder ( elements [ largest] , elements [ right] ) ) {
536
- largest = right
524
+ while countToIndex + 1 < countFromIndex {
525
+ let left = elements. index ( i, offsetBy: countToIndex + 1 )
526
+ var largest = i
527
+ if try areInIncreasingOrder ( elements [ largest] , elements [ left] ) {
528
+ largest = left
529
+ }
530
+ // Check if right child is also within bounds before trying to examine it.
531
+ if countToIndex + 2 < countFromIndex {
532
+ let right = elements. index ( after: left)
533
+ if try areInIncreasingOrder ( elements [ largest] , elements [ right] ) {
534
+ largest = right
535
+ }
536
+ }
537
+ // If a child is bigger than the current node, swap them and continue sifting
538
+ // down.
539
+ if largest != i {
540
+ elements. swapAt ( index, largest)
541
+ i = largest
542
+ countToIndex = elements. distance ( from: range. lowerBound, to: i)
543
+ countFromIndex = elements. distance ( from: i, to: range. upperBound)
544
+ } else {
545
+ break
537
546
}
538
- }
539
- // If a child is bigger than the current node, swap them and continue sifting
540
- // down.
541
- if largest != index {
542
- elements. swapAt ( index, largest)
543
- try _siftDown (
544
- & elements,
545
- index: largest,
546
- subRange: range
547
- , by: areInIncreasingOrder)
548
547
}
549
548
}
550
549
0 commit comments