链表的这种实现被打破了。节点[0] .next的地址与节点[1]地址不匹配。所以nodes [1] .next为NULL(默认值)。我在搜索方法中添加了一些地址打印。看起来节点[1]没有被初始化?
#include <iostream>
#include <vector>
using namespace std;
typedef struct Node_T {
int data;
Node_T *next;
} Node;
class LinkedList{
public:
vector<Node> nodes;
LinkedList(){
}
void insert(int data) {
Node temp_node;
temp_node.data = data;
temp_node.next = NULL;
size_t len = nodes.size();
nodes.push_back(temp_node);
if (len > 0) {
nodes[len - 1].next = &nodes[len];
}
}
int search(int val){
if (nodes.empty())
return -1;
Node *node_ptr = &nodes[0];
// Debug
cout << &nodes[1] << "\n";
cout << &nodes[0].next << "\n";
int i = 0;
do {
if (node_ptr->data == val) return i;
i++;
} while((node_ptr = node_ptr->next) != NULL);
return -1;
}
};
int main()
{
LinkedList llist;
llist.insert(1);
llist.insert(2);
llist.insert(3);
llist.insert(4);
llist.insert(5);
cout << llist.search(3) << "\n";
return 0;
}
它告诉我:0x8e6a060 0x8e6a05c -1
答案 0 :(得分:3)
向vector
添加元素时,对向量元素的引用(以及因此地址)无效。因此,您必须不使用&nodes[0]
或&nodes[len]
等值,因为它们毫无意义。
答案 1 :(得分:3)
这样的练习要点就是将内部结构挂在链表中。您已使用vector<Node>
替换了该内部结构。
而不是矢量,我们的想法是拥有
private:
Node* head;
作为数据成员。
在插入函数中,您应该使用
为节点动态分配内存Node* newNodePointer = new Node;
用下一个操作指针。
值得指出的是,这可以作为一种练习,但你的真实&#34;代码应该使用标准库设施。
答案 2 :(得分:2)
首先,您的打印输出不正确:此行
cout << &nodes[0].next << "\n";
打印next
的地址,而不是打印next
本身。改为
cout << nodes[0].next << "\n";
给出正确的打印输出(demo)。
但是,主要问题是您保留指向std::vector
元素的指针。这些在第一次写入后变为无效,因为新存储被分配给不断增长的向量。
您当然可以通过预先留出足够的空间(从列表的构造函数调用nodes.reserve(1000)
; demo)解决此问题,但这只是一个黑客攻击:您应该使用new
和delete
手动分配链接列表的元素。这就是这项工作的重点。
但是我仍然需要一个容器来确保节点按预期生效?
不,你没有。您的班级 是一个容器。通过从头指针引用整个节点链,它可以确保整个链保持“实时”。