forked from lchenay/VPTree-Swift
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathArray.swift
More file actions
73 lines (61 loc) · 1.8 KB
/
Array.swift
File metadata and controls
73 lines (61 loc) · 1.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import Foundation
private func splitArray<T: Comparable>(
_ array: inout [T],
_ nbItemLeft: Int,
_ nbItemRight: Int
) -> (Array<T>, Array<T>) {
var left: Array<T> = []
var right: Array<T> = []
var middle: Array<T> = []
left.reserveCapacity(nbItemLeft)
right.reserveCapacity(nbItemRight)
if (nbItemLeft == 0) {
return (left, array)
}
if (nbItemRight == 0) {
return (array, right)
}
if (nbItemLeft == 1 && nbItemRight == 1) {
if array[0] < array[1] {
return ([array[0]], [array[1]])
} else {
return ([array[1]], [array[0]])
}
}
let pivot: T = array[nbItemLeft]
for element in array {
if element < pivot {
left.append(element)
} else if element > pivot {
right.append(element)
} else {
middle.append(element)
}
}
while (left.count < nbItemLeft && middle.count > 0) {
left.append(middle.removeLast());
}
while (middle.count > 0) {
right.append(middle.removeLast());
}
if left.count > nbItemLeft {
let sub: (left: [T], right: [T])
= splitArray(&left, nbItemLeft, nbItemRight - right.count)
return (sub.left, right + sub.right)
} else if right.count > nbItemRight {
let sub: (left: [T], right: [T])
= splitArray(&right, nbItemLeft - left.count, nbItemRight)
return (left + sub.left, sub.right)
} else {
return (left, right)
}
}
internal extension Array {
func splitByMedian<T>() -> ([T], [T]) where T: Comparable {
let mid = count / 2
var array: Array<T> = self.map {
return $0 as! T
}
return splitArray(&array, count-mid, mid)
}
}