我有某种类型A
的索引集合(必须编入索引):
var coll: IndexedSeq[A]
我希望coll
根据某些Ordering[A]
排序,但我经常在其中添加/删除项目。这样做的明显机制是:
def binarySearch[A : Ordering](a: IndexedSeq[A], elem: A): Int
def add(a: A) {
val idx = binarySearch(coll, a)
coll = (coll take idx) :+ a +: (coll drop idx)
}
但是标准库中没有binarySearch
(奇怪的是,看到有scala.util.Sorting.quickSort
)并且没有我能找到的数据类型,它既被索引又被排序(我猜这是效率低下的结构。)
答案 0 :(得分:3)
我认为slice
上TreeSet
的效率相当高(并且你可以将它用于单元素范围),但你是对的 - 奇怪的是没有索引排序的数据结构。它足够有效;如果跟踪孩子的数量,大多数任何排序的树都可以这样使用。我认为这只是一种疏忽而已。但
如果用一个只允许引用相等的标记包装它们,你总是可以使用一个重复元素集,并且你可以确保它们是有序的:
class Tag[A](val value: A)(implicit ord: Ordering[A]) extends Ordered[Tag[A]] {
def compare(ta: Tag[A]) = {
val c = ord.compare(value,ta.value)
if (c != 0) c
else if (this eq ta) 0
else System.identityHashCode(this) compare System.identityHashCode(ta)
}
override def toString = value.toString+"'"
override def hashCode = value.hashCode
override def equals(a: Any) = a.asInstanceOf[AnyRef] eq this
}
scala> collection.immutable.TreeSet[Tag[Int]]() ++ List(1,2,3,2,1).map(i => new Tag(i))
res1: scala.collection.immutable.TreeSet[Tag[Int]] = TreeSet(1', 1', 2', 2', 3')
scala> res1.slice(2,3).head
res2: Tag[Int] = 2'
然而,这确实为相对简单的任务增加了很多开销。
答案 1 :(得分:2)
http://www.scala-lang.org/api/2.11.4/index.html#scala.collection.Searching $$ SearchImpl
在特定元素的排序序列中的间隔内搜索。如果序列是IndexedSeq,则使用二进制搜索。否则,使用线性搜索。
答案 2 :(得分:0)
def getPerson(userList: ArrayList[Person], person: Person): Integer = {
var low = 0;
var high = userList.size - 1
while (low <= high) {
var mid = low + (high - low) / 2
var midValue = userList.get(mid)
if (person.firstName < midValue.firstName) {
high = mid - 1;
} else if (person.firstName > midValue.firstName) {
low = mid + 1;
} else {
return mid
}
}
return -1
}