[英]vector<pointer>::insert(iterator,pointer) inserting garbage value
I am writing a recursive function to print all the possible permutations of keys which will give the same Binary Search tree.我正在编写一个递归 function 来打印所有可能的键排列,这将给出相同的二叉搜索树。
At every node I am storing the next possible nodes in a vector(ie, deleting that node and adding its children) and recursively calling the function.在每个节点上,我将下一个可能的节点存储在一个向量中(即删除该节点并添加其子节点)并递归调用 function。 I am printing the keys once there are no more nodes to add.(I know I can use vector instead of stack but I am just learning vectors).一旦没有更多节点要添加,我就会打印密钥。(我知道我可以使用向量而不是堆栈,但我只是在学习向量)。
#include<bits/stdc++.h>
#define child c
using namespace std;
typedef
struct bstnode
{
bstnode *lc;
int x;
int data;
bstnode *rc;
}* BSTPTR;
//Prints the inorder of a BST
void printIn(BSTPTR T)
{
if(T)
{
printIn(T->lc);
cout<<T->data<<' ';
printIn(T->rc);
}
}
//adds an element to a BST
void add(BSTPTR &T,int k)
{
if(T)
{
if(k < T->data)
add(T->lc,k);
else
add(T->rc,k);
}
else
{
BSTPTR t = new bstnode;
t->data = k;
t->lc=t->rc=NULL;
T = t;
}
}
//prints all the permutations in question
void printPermute(vector<BSTPTR> &LIST,BSTPTR T,stack<int> p)
{
if(LIST.size()==0)
{
stack<int> q;
int n=p.size();
while(!p.empty())
{
q.push(p.top());
p.pop();
}
int flag=1;
int i=0,A[]={18,12,15,5,9,36,72,45,30};
while(!q.empty())
{
int x=q.top();
if(A[i++]!=x)
flag=0;
cout<<x<<' ';
q.pop();
p.push(x);
}
if(flag)
{
int f=9;
f++;
}
cout<<endl;
}
else
{
for(auto i=LIST.begin();i<LIST.end();++i)
{
BSTPTR t=*i;
p.push(t->data);
LIST.erase(i);
if(t->lc)
{
LIST.push_back(t->lc);
if(t->rc)
{
LIST.push_back(t->rc);
printPermute(LIST,t,p);
LIST.pop_back();
}
else
{
printPermute(LIST,t,p);
}
LIST.pop_back();
}
else
{
if(t->rc)
{
LIST.push_back(t->rc);
printPermute(LIST,t,p);
LIST.pop_back();
}
else
{
printPermute(LIST,t,p);
}
}
p.pop();
LIST.insert(i,t);
}
}
}
//this is a helping function to asitis(BSTPTR) assigns the value of x for each node
void assignX(BSTPTR T,int &x)
{
if(T)
{
if(T->lc == NULL)
{
T->x = x++;
assignX(T->rc, x);
}
else
{
assignX(T->lc, x);
T->x = x++;
assignX(T->rc, x);
}
}
}
//prints the tree as it would look on paper. This is to give an intuitive idea of the tree's structure
void asItIs(BSTPTR T)
{
int prev;
assignX(T,prev=1);
prev=0;
queue<BSTPTR> q;
q.push(T);
q.push(NULL);
while(q.size()>1)
{
BSTPTR t = q.front();
q.pop();
if(t)
{
for(int i=0;i<t->x-1-prev;++i)
cout<<' ';
cout<<t->data;
prev = t->x;
if(t->lc)
q.push(t->lc);
if(t->rc)
q.push(t->rc);
}
else
{
cout<<endl;
prev = 0;
q.push(t);
}
}
cout<<endl;
}
int main()
{
BSTPTR T = NULL;
cout<<"Enter the numbers in the tree:\n";
int i=0,A[] = {18,12,36,5,15,30,72,9,45,-5};
while(A[i]>=0)
{
add(T,A[i++]);
}
printIn(T);
cout<<endl;
asItIs(T);
vector<BSTPTR> LIST;
stack<int> p;
LIST.push_back(T);
// cout<<LIST.size();
printPermute(LIST,T,p);
}
So my code is printing all the possible permutations starting with 18 12 but when it has to insert the node containing 12 at the end of the loop in second recursion:所以我的代码正在打印所有可能的排列,从 18 12 开始,但是当它必须在第二次递归的循环末尾插入包含 12 的节点时:
//main::printPermute(only 1 iteration of for loop is there)::printPermute(at the end of 1st iteration out of 2 iterations
LIST.insert(i,t);
instead of inserting the address of that node containg the key 12 which is stored in t,it is inserting (I hope it is) a garbage value "ox31".它不是插入包含存储在 t 中的密钥 12 的那个节点的地址,而是插入(我希望它是)一个垃圾值“ox31”。 Now this obviously messes up the furthur execution.现在这显然会扰乱进一步的执行。
Why is it inserting such a value?为什么要插入这样的值? This is more intriguing because this problem did not occur in higher levels of recursion(There are in total some 9 or 10 levels).这更有趣,因为这个问题并没有出现在更高级别的递归中(总共有大约 9 或 10 个级别)。
for(auto i=LIST.begin();i<LIST.end();++i) {
LIST.erase(i);
LIST.insert(i,t);
...
The erase
call invalidates the iterator to the element being erased - namely, i
. erase
调用使被擦除元素的迭代器无效 - 即i
。 Then LIST.insert(i,t)
exhibits undefined behavior by way of accessing now-invalid iterator.然后LIST.insert(i,t)
通过访问现在无效的迭代器表现出未定义的行为。
Further, LIST.push_back()
may invalidate all iterators into the list, including i
(had it not been invalidated already).此外, LIST.push_back()
可能会使列表中的所有迭代器失效,包括i
(如果它还没有失效的话)。
You may want to use an index, rather than an iterator, to iterate over the list, since you are modifying it so much.您可能希望使用索引而不是迭代器来迭代列表,因为您正在对其进行大量修改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.