我有一个简单的算法,它返回一个列表列表,其中每个内部列表包含二叉树不同级别的节点。我无法理解如何重置"我内心清单的范围(例如见下文)。
我的树是一棵简单的玩具树,如下:
struct Node {
int data;
Node *left, *right;
}
我使用一个简单的bfs,它应该返回一个列表列表。我尝试在每个循环上创建一个新列表,但我不确定如何清除"列表并开始一个新的。
std::vector< std::vector<Node *> > build_lists(Node *root) {
std::vector< std::vector<Node *> > result;
Node *newline = new Node { std::numeric_limits<int>::min(), nullptr, nullptr };
std::deque<int> q;
q.push_back(root);
q.push_back(newline);
Node *tmp;
std::vector<Node *> inner; // HERE IS WHERE IS SET THE FIRST INNER VECTOR
while(!q.empty()) {
tmp = q.front();
q.pop_front();
if (tmp == newline) {
result.push_back(inner);
std::vector<Node *> inner; // HERE IS WHERE I TRY TO ''RESET'' THE VECTOR
if (!q.empty())
q.push_back(newline);
} else {
inner.push_back(tmp);
if (tmp->left)
q.push_back(tmp->left);
if (tmp->right)
q.push_back(tmp->right);
}
}
}
显然,我无法理解范围和一些基本语言功能。如果有人能帮助我指出正确的方向,我将不胜感激。
答案 0 :(得分:2)
您无法通过再次声明变量来重置变量,这正是您的代码正在执行的操作。您现在有一个具有相同名称的第二个变量,在第二个变量的持续时间内,该名称指向第二个变量。
相反,您需要使用方法来清除第一个变量。
vector
确实有method to reset it's contents - vector::clear
。
你应该这样做:
result.push_back(inner);
// std::vector<Node *> inner;
inner.clear();
如果你需要清除你已经推入向量内的东西,你可以这样做:
vector< vector< int > > vvi;
vector< int > vi;
vi.push_back(1); // fill
vii.push_back(vi); // vii has a copy of vi as it is now.
auto & _v = vii[0]; // fetch a reference to the copy
_v.clear(); // clear it
vii[0].clear(); // same in one step
assert( vii[0].size() == 0 ); // still contains a vector at index 0 but it's empty
尽管您要清除指针的向量 - 正如其他人指出的那样(ha),您需要非常小心,不要“忘记”指针。
例如,这会很糟糕:
vector< int* > x;
x.push_back( new int(4) );
x.clear(); // leak
答案 1 :(得分:0)
为了使对象超出范围,必须创建 INSIDE 循环,例如:
while(1) {
std::vector<int> v;
...
// at that point 'v' will go out of scope and thus destroyed
}
但是,当你这样做时:
std::vector<int> v;
while(1) {
...
// 'v' is always the same at this point
}
您可以使用std::vector::clear()重置矢量,但要小心,因为您正在使用指针。除非你跟踪指向的对象,否则只需清除向量就会导致悬空指针,从而未定义的行为,你不希望这种情况发生。
如果你需要释放指针指向的内存,那么你应该首先删除指针指向的对象,然后然后清除向量。