Reputation: 69
I am trying to implement a skiplist in cpp . There are many versions of skiplist available but I particularly want to implement a version where each node has a right and down pointer to form a connected list at various levels . Also at each higher level there is a replica of node rather than just a pointer.
I am giving my code that I have implemented uptill now. There is only one function that I have implemented till now i.e insertion. But I am getting segmentation fault. I know I am messing somewhere with pointers somewhere either in constructor, update or insert functions. Can somebody please help.
class SkipList
{
private:
struct node {
int key;
int data;
int level;
struct node* rgt = nullptr;
struct node* dwn = nullptr ;
node(int k, int value, int l):
key(k), data(value), level(l)
{}
};
//generates the ndde level in tha range [1,maxLevel).
int randomLevel() const;
//returns a set of pointers to the location at each node where new links are to be created
std::vector<node*> update(int searchKey) const ;
//creates a new node and returns a pointer to it
static node* makeNode(int key, int val, int level);
const float probability;
const int maxLevel;
// head and tail vectors
vector<node*> head;
vector<node*> nil;
public:
SkipList();
~SkipList();
void insert(int searchKey, int val);
void print() const;
};
SkipList::SkipList() :
probability(0.5), maxLevel(16)
{
int headkey = std::numeric_limits<int>::min();
int nilkey = std::numeric_limits<int>::max();
for(int i = 0; i < maxLevel;i++)
{
head[i] = new node(headkey,0,maxLevel-1);
nil[i] = new node(nilkey,0,maxLevel-1);
if(i > 0)
{
head[i]-> dwn = nil[i-1];
nil[i] -> dwn = nil[i-1];
}
head[i]->rgt = nil[i];
}
}
void SkipList::insert(int searchKey, int val)
{
vector <node*> preds = update(searchKey);
node* temp;
const int newLevel = randomLevel();
for(int i = 0; i< newLevel; i++)
{
node* ptr = makeNode(searchKey,val, newLevel-1);
temp = preds[i]->rgt;
preds[i]->rgt = ptr;
ptr->rgt = temp;
}
}
void SkipList::print() const{
node* list = head[0]->rgt;
int lineLength = 0;
std::cout<<"{";
while (list->rgt != nil[list->level])
{
std::cout<<"value: "<<list->data
<<", key: "<<list->key
<<", level: "<<list->level;
list = list->rgt;
if(list->rgt != nil[list->level]) std::cout<<" : ";
if (++lineLength % 2 == 0) std::cout << "\n";
}
std::cout << "}\n";
}
int SkipList::randomLevel() const{
int v = 1;
while (((double)std::rand() / RAND_MAX) < probability
&& v < maxLevel)
{
v++;
}
return v;
}
SkipList::node* SkipList::makeNode(int key, int value, int level){
return new node(key, value, level);
}
std::vector<SkipList::node*>SkipList::update(int searchKey) const{
int level = head[0]->level;
std::vector<node*> result(level,nullptr);
node* x ;
for(unsigned int i = level;i-- >0;)
{
x = head[i];
while(x->rgt->key < searchKey)
{
x = x->rgt;
}
result[i]= x;
}
return result;
}
int main()
{
SkipList s;
s.insert(5,22);
s.insert(2,33);
s.print();
return 0;
}
Upvotes: 0
Views: 2841
Reputation: 20934
You should use push_back method in ctor of SkipList. Now you are creating objects
head[i] = new node(headkey,0,maxLevel-1);
and you are trying to assign the created node object to object returned by vector::operator[]
which doesn't exist.
Or you can invoke vector::resize(maxlevel)
method before entering into for loop.
Upvotes: 1