2017-07-30 113 views
-1

醫生說斯卡拉:列表性能

時間:列表中包含了O(1)前插和頭/尾的訪問。大多數其他 操作都是O(n)列表中元素的數量。這個 包括基於索引的元素查找,長度,追加和逆向。

Docs「自豪地」提到大多數操作都是O(n)。即使它通過鏈表進行備份,長度和附加操作也可以很容易地保持一致。也不知道我是否明白爲什麼它不是雙向鏈表,這會使O(1)反向操作。

這是功能強大的巨無霸,不是嗎?

[編輯]哪個集合可以給我所有上述操作的O(1)?

回答

3

不變性是答案。這是一個簡化版本的實施清單

trait List[+A] { 
    def prepend[A1 >: A](a:A1): List[A] 
} 
case class Cons[A](head: A, tail: List[A]) extends List[A] { 
    def prepend[A1 >: A](a:A1): List[A1] = Cons(a, this) 
} 
case object Nil extends List[Nothing] { 
    def prepend[A1 >: A](a:A1): List[A1] = Cons(a, Nil) 
} 

有了這個ADT,你可以預先安排但不能創建一個雙向鏈表。讓我們瑟爲例

val list1 = Cons(1, Cons(2, Nil)) 
val list2 = Cons(0, list1) 
val list3 = Cons(-1, list1) 

這不能被實現爲doublylinked列表,而當您創建列表2和項目list3

+0

感謝您的回答!我瞭解不變性是原因,但它帶有成本。如果它無法保存集合中的元素總數,那有什麼意義? – Programmer

+0

是的,它有一個成本。列表不是您應該用於每個問題的集合,但毫無疑問,您只需要按順序和/或預先讀取元素,就可以獲得最佳性能的集合 – Mikel