多层插入方法:记录搜索路径中向下的节点,插入新节点时弹出节点。
struct Node{
Node *right,*down; //向右向下足矣
int val;
Node(Node *right,Node *down,int val):right(right),down(down),val(val){}
};
class Skiplist {
private:
Node *head;
public:
Skiplist() {
head=new Node(NULL,NULL,-1); //初始化头结点
}
bool search(int target) {
Node *p=head;
while(p){
while(p->right && p->right->val<target){ //寻找目标区间,基本就是这个思路
p=p->right;
}
if(!p->right || target<p->right->val){ //没找到目标值,则继续往下走
p=p->down;
}else{ //找到目标值,结束
return true;
}
}
return false;
}
void add(int num) {
vector<Node*> pathList; //从上至下记录搜索路径
Node *p=head;
while(p){
while(p->right && p->right->val<num){
p=p->right;
}
pathList.push_back(p);
p=p->down;
}
bool insertUp=true;
Node* downNode=NULL;
while(insertUp && pathList.size()>0){ //从下至上搜索路径回溯,50%概率
Node *insert=pathList.back();
pathList.pop_back();
insert->right=new Node(insert->right,downNode,num); //add新结点
downNode=insert->right; //把新结点赋值为downNode
insertUp=(rand()&1)==0; //50%概率
}
if(insertUp){ //插入新的头结点,加层
head=new Node(new Node(NULL,downNode,num),head,-1);
}
}
bool erase(int num) {
Node *p=head;
bool seen=false;
while(p){
while(p->right && p->right->val<num){
p=p->right;
}
if(!p->right ||p->right->val>num){
p=p->down;
}else{ //搜索到目标结点,进行删除操作,结果记录为true,继续往下层搜索,删除一组目标结点
seen=true;
p->right=p->right->right;
p=p->down;
}
}
return seen;
}
};
链接:https://leetcode-cn.com/problems/design-skiplist/solution/cbi-jiao-qing-xi-de-dai-ma-shi-xian-by-jsond/