Scala 索引集合(已排序的索引序列)上的二进制搜索
我有一个索引的集合(它必须被索引),属于某种类型的Scala 索引集合(已排序的索引序列)上的二进制搜索,scala,indexing,binary-search,Scala,Indexing,Binary Search,我有一个索引的集合(它必须被索引),属于某种类型的A: var coll: IndexedSeq[A] 我希望根据一些排序[A]对coll进行排序,但我经常在其中添加/删除项目。这样做的明显机制如下: def binarySearch[A : Ordering](a: IndexedSeq[A], elem: A): Int def add(a: A) { val idx = binarySearch(coll, a) coll = (coll take idx) :+ a +: (c
A
:
var coll: IndexedSeq[A]
我希望根据一些排序[A]对coll
进行排序,但我经常在其中添加/删除项目。这样做的明显机制如下:
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
),也没有可以找到索引和排序的数据类型(我想这是一个低效的结构)。我认为TreeSet
上的slice
相当有效(您可以将其用于一个元素范围),但您是对的——奇怪的是,没有索引排序的数据结构。而且它足够有效;如果跟踪子级的数量,大多数排序树都可以这样使用。我认为这只是一个遗漏
如果使用仅允许引用相等的标记对重复元素进行包装,则始终可以使用重复元素集,并且可以确保重复元素的顺序:
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'
但是,对于一个相对简单的任务来说,这确实会增加很多开销。def getPerson(userList:ArrayList[Person],Person:Person):Integer={
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
var-low=0;
var high=userList.size-1
while(低中值。firstName){
低=中+1;
}否则{
中途返回
}
}
返回-1
}$$SearchImpl
在排序序列中的间隔内搜索特定元素。如果序列是IndexedSeq,则使用二进制搜索。否则,使用线性搜索
树具有O(logn)元素访问权限。我认为
IndexedSeq
意味着O(1)访问权限。此外,基于Ordered
,不可能存在O(1)(用于插入)排序集合,因为按成对比较排序至少是O(nlogn)。@ziggystar-IndexedSeq
不保证是O(1)访问。看看List
!@RexKerrList
不是IndexedSeq
,IndexedSeq
确实应该具有“恒定时间或接近恒定时间的元素访问和长度计算”(scaladoc 2.9.1)。有趣的是-我猜这里基于索引的访问不会是O(1)-这可能有问题,因为这是TableModel
@oxbow的支持数据结构。您可以拥有O(1)读访问权限,但不能拥有O(1)写访问权限。您在OP中的示例演示了这一点。您是否可以为询问者添加解释和解释,这也将帮助您获得更多选票