Skip to content

search algorithm doesn't take duplicate keys into account #16

Closed
@Mamonaku

Description

@Mamonaku

Hello,
I think the algorithm :

fileprivate func search(for newElement: Element) -> Match<Index> {
    guard !isEmpty else { return .notFound(insertAt: endIndex) }
    var left = startIndex
    var right = index(before: endIndex)
    while left <= right {
        let dist = distance(from: left, to: right)
        let mid = index(left, offsetBy: dist/2)
        let candidate = self[mid]

        if areInIncreasingOrder(candidate, newElement) {
            left = index(after: mid)
        } else if areInIncreasingOrder(newElement, candidate) {
            right = index(before: mid)
        } else {
            // If neither element comes before the other, they _must_ be
            // equal, per the strict ordering requirement of `areInIncreasingOrder`.
            return .found(at: mid)
        }
    }
    // Not found. left is the index where this element should be placed if it were inserted.
    return .notFound(insertAt: left)
}

Doesn't take into account the case where duplicate keys are present. In particular, in calculating the mid point, it'll give the index value of the first occurence of newElement == candidate, not the smallest index.

As a result, enumerating all keys verifying k == 0 (for example), will fail. One has to find the lowest value for which areInIncreasingOrder(candidate, newElement) == true and areInIncreasingOrder(newElement, candidate + 1) == false.

If I find a quick solution, I'll let you know.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions