我正在用C ++构建一个跳转列表的实现,该列表具有到周围节点的四重链接。
这是跳过列表节点类:
class SkipList_Node {
public:
int key;
string data;
//special values for infinity keys
int pos_infinity_key = 1000;
int neg_infinity_key = -1000;
//pointers to surrounding nodes
SkipList_Node *up;
SkipList_Node *down;
SkipList_Node *left;
SkipList_Node *right;
//Constructors
SkipList_Node() {};
SkipList_Node(int k, string d) {
this->key = k;
this->data = d;
up = NULL;
down = NULL;
left = NULL;
right = NULL;
}
};
这是“跳过”列表类。
class Skip_List {
public:
//first and last nodes in the list
SkipList_Node first;
SkipList_Node last;
//Number of rows in the list
int height;
//Constructor for an empty skiplist
Skip_List() {
//initialize infinity keys
SkipList_Node node1(SkipList_Node().neg_infinity_key, "");
SkipList_Node node2(SkipList_Node().pos_infinity_key, "");
//link new nodes
node1.right = &node2;
node2.left = &node1;
//update first and last key values
first = node1;
last = node2;
height = 0;
}
//Randomly determine the height of a node
int getLevel() {
//set the seed for random function
srand(time(NULL));
//Simulate coin flips and store heads into array
//Max height is 4
int flips[5];
for (int i = 0; i < 5; i++) {
flips[i] = 1 + rand() % 2;
}
//Determine height based on heads
//As soon as tails is fliped stop counting height
int height_counter = 0;
for (int n = 0; n < 5; n++) {
if (flips[n] == 2) {
height_counter += 1;
}
else {
break;
}
}
return height_counter;
}
//return height of the skip list
int getHeight() {
return height;
}
//find the largest key which is <= value of key passed
SkipList_Node searchSkipList(int k) {
//pointer to the node
SkipList_Node* ptr;
//point to the first node of the list
ptr = &first;
//move right until a key <= value of key passed is found
while (1) {
while (ptr->right->key != SkipList_Node().neg_infinity_key &&
((ptr->right->key) - k) <= 0) {
ptr = ptr->right;
}
//drop down level
if (ptr->down != NULL) {
ptr = ptr->down;
}
else {
//Lowest level of skip list reached
break;
}
}
return *ptr;
}
//Return the value of a node given the key
string getValue(int k){
SkipList_Node* ptr;
//search for the node
ptr = &searchSkipList(k);
//If key is found return its value else return null
if (k == (ptr->key)) {
return ptr->data;
}
else {
cout << "No Nodes found with that key value";
return NULL;
}
}
//Insert a new node into skip list
void insertIntoSkiplist(int k, string d) {
SkipList_Node* p;
int level;
p = &searchSkipList(k);
//if key already exists update the value
if (k == (p->key)) {
p->data = d;
return;
}
// Create and insert a new node
SkipList_Node* q = new SkipList_Node(k, d);
q->left = p;
q->right = p->right;
p->right->left = q;
p->right = q;
//Calculate the level
level = getLevel();
//insert node in each level
for (int i = 0; i <= level; i++) {
//Create new empty row if level is hiegher than the current height of the list
if (level >= height) {
SkipList_Node* node1 = new SkipList_Node(SkipList_Node().neg_infinity_key, "");
SkipList_Node* node2 = new SkipList_Node(SkipList_Node().pos_infinity_key, "");
//link inifnity nodes
node1->right = node2;
node1->down = &first;
node2->left = node1;
node2->down = &last;
first.up = node1;
last.up = node2;
first = *node1;
last = *node2;
}
while (p->up == NULL) {
p = p->left;
}
p = p->up;
SkipList_Node* z = new SkipList_Node(k, NULL);
z->left = p;
z->right = p->right;
z->down = q;
p -> right -> left = z;
p->right = z;
q->up = z;
q = z;
level += 1;
}
}
};
主要,我创建一个新的跳过列表对象。查看调试器,构造函数成功创建了node1和node2,并使用它们首先更新了节点,最后更新了节点。此时,节点first和last具有正确的链接值,First.right的键为1000,last.left的键为-1000。
然后我调用insertIntoSkipList()方法,该方法又调用searchSkipList()方法。在我将first的内存地址分配给指针ptr的那一点上看调试器,first.right的值现在为key = -858993和data =“错误读取字符串字符”。我不确定为什么first的内存地址将这些值保存为指向正确节点的指针。在这一点上,我希望first.right仍然保持key = 1000和data =“”的值,然后由ptr-> right指向。
我对C ++和指针没有太多经验。
答案 0 :(得分:0)
您正在将左右指针分配给临时对象的地址。 SkipList构造函数运行后,它们就会超出范围,现在您有了悬空的指针。
如果需要永久引用,则需要分配内存。在cplusplus.com上查看指针和内存:
http://www.cplusplus.com/doc/tutorial/pointers/ http://www.cplusplus.com/doc/tutorial/dynamic/