Какова внутренняя реализация списков?
Мне любопытно, как объект типаlist
реализовано. Это
O(1)
, но доступ к элементуO(n)
.древовидная структура сO(log(n))
доступ к элементу.Hashtable сO(1)
доступ к элементу.Мне любопытно, потому что списки могут иметь пары ключ-значение, которые делают их похожими на хеш-таблицы, но элементы расположены по порядку, который выглядит как вектор.
редактировать: потому чтоlength(list(runif(1e4)))
равен 1, поэтому при добавлении элемента в список создается впечатление, что он копирует весь список каждый раз, что делает его очень медленным:
Но скорость доступа намного ниже, чем у вектора:
z1 <- runif(1e4)
system.time({
for(i in 1:10000) z1[[1 + i]] <- 1
})
выходы:
user system elapsed
0.060 0.000 0.062
но:
z1 <- list(runif(1e4))
system.time({
for(i in 1:10000) z1[[1 + i]] <- 1
})
выходы:
user system elapsed
1.31 0.00 1.31
инициировать список из 10000 элементов:
z1 <- as.list(runif(1e4))
system.time({
for(i in 1:10000) z1[[1 + i]] <- 1
})
выходы:
user system elapsed
0.060 0.000 0.065
Для доступа к ключу и значению:
z1 <- list()
for(i in 1:10000){key <- as.character(i); z1[[key]] <- i}
system.time({
for(i in 1:10000) x <- z1[["1"]]
})
system.time({
for(i in 1:10000) x <- z1[["10000"]]
})
Выход:
user system elapsed
0.01 0.00 0.01
user system elapsed
1.78 0.00 1.78
Это неO(1)
доступ, так что это не хеш-таблица. Мой вывод заключается в том, что это не динамический массив, так как добавление элементов будет вызывать доступ к памяти каждый раз; это не хеш-таблица, так как доступ по ключу неO(1)
.