在插入时,通过计算每个前驱节点到当前节点的距离,保存在当前节点中,并且修改后驱节点的距离值,就可以实现log(n)的下标索引了
void SkipList<Key, Comparator>::SetCount(Node** prev, Node *node, int height)
{
node->SetCount(0, 1);
for (int level = 1; level < height; level++)
{
int count = 0;
for (Node* begin = prev[level]->Next(level-1); begin != node->Next(level-1); begin = begin->Next(level-1))
{
count += begin->Count(level-1);
}
node->SetCount(level, count);
auto after = node->Next(level);
if (after != nullptr)
{
int afterCount = after->Count(level);
after->SetCount(level,afterCount - count + 1);
}
}
for (int level = height; level < GetMaxHeight(); level++) {
auto after = prev[level]->Next(level);
if (after) {
after->SetCount(level, after->Count(level) +1);
}
}
}
Node* operator [](int index)
{
int level = kMaxHeight - 1;
int count = 0;
Node* p = head_;
while(level >=0) {
// 如果有下一针,并且下一帧个数和还是比目标小,就继续后移
auto after = p->Next(level);
if (after) {
auto afterCount = after->Count(level);
if (count + afterCount < index)
{
count += afterCount;
p = after;
continue;
}
else if (count + afterCount == index)
{
return after;
}
}
level--;
}
}