#ifndef BINARY_TREE_H
#define BINARY_TREE_H
#include<iostream>
#include<vector>
using namespace std;
class Binary_Tree;
static int levelCount=0;
extern vector<vector<Binary_Tree*>> vec;
extern vector<Binary_Tree*> tempVec;
class Binary_Tree
{
public:
Binary_Tree()
{
childNum=0;
data=0;
level=0;
prev=NULL;
next[0]=NULL;
next[1]=NULL;
};
Binary_Tree(int d)
{
childNum=0;
data=d;
level=0;
prev=NULL;
next[0]=NULL;
next[1]=NULL;
levelCount++;
}
void insert_node(int,int,int);
int get_level();
int get_childCount();
friend int set_childNum(Binary_Tree*);
private:
int childNum;
int data;
int level;
Binary_Tree *prev;
Binary_Tree *next[2];
};
#endif // BINARY_TREE_H
这是实施文件
#include<iostream>
#include<cmath>
#include "Binary_Tree.h"
using namespace std;
void Binary_Tree::insert_node(int lev, int d, int sib)
{
if(vec.empty())
{
cout<<"You Have to create Root first";
}
else
{
if(set_childNum(vec[lev][sib-1])==0)
{
cout<<"Child cant be created parent Node already has two childs.";
}
else
{
childNum=set_childNum(vec[lev][sib-1]);
data=d;
level=lev+1;
prev=vec[lev][sib];
next[0]=NULL;
next[1]=NULL;
tempVec.clear();
for(int i=0; i<pow(2,(lev+1)); i++)
{
if(i==childNum-1)
{
tempVec.push_back(this);
}
else
tempVec.push_back(vec[lev][i]);
}
vector<vector<Binary_Tree*>>::iterator itr=vec.begin()+(lev+1);
vec.erase(itr);
vec.insert(itr,tempVec);
}
}
}
int set_childNum(Binary_Tree *lstNdAdr)
{
if(lstNdAdr->get_childCount()==0)
return 1;
else if(lstNdAdr->get_childCount()==1)
return 2;
else
return 0;
}
int Binary_Tree::get_level()
{
return level;
}
int Binary_Tree::get_childCount()
{
if(next[0]==NULL)
{
return 0;
}
else if(next[0]!=NULL && next[1]==NULL)
{
return 1;
}
else
{
return 2;
}
}
的main.cpp
#include <iostream>
#include<cmath>
#include"Binary_Tree.h"
using namespace std;
vector<vector<Binary_Tree*>> vec;
vector<Binary_Tree*> tempVec;
int main()
{
Binary_Tree tree;
here:
cout<<"Enter your Choice:1.Create Root Of Tree\n"
<<"2.Insert node\n"<<endl;
int choice;
cin>>choice;
switch(choice)
{
case 1:
{
int d;
cout<<"Enter Data to insert: ";
cin>>d;
Binary_Tree treeDummy(d);
tree=treeDummy;
tempVec.push_back(&tree);
vec.push_back(tempVec);
}
break;
case 2:
{
int lev;
int sibbling;
int d;
cout<<"Enter at which level and data and parent's sibling-no.: ";
cin>>lev;
cin>>d;
cin>>sibbling;
if(sibbling>pow(2,lev))
cout<<"Illegal Sibbling Number."<<endl;
else
tree.insert_node(lev,d,sibbling);
}
break;
}
int x;
cin>>x;
if(x==5)
{
cout<<endl<<endl;
goto here;
}
return 0;
}
在上面的代码中我试图创建一个二进制树类型结构,可以动态地操作和遍历,任何节点都可以插入,并且可以在运行时删除(虽然它不完整,因为我遇到了问题)。在推回tempVec
向量时,代码会产生分段错误,而且我也怀疑传递存储在vetcor中的对象&gt; vec到实现中的函数(我是Stl的新手,第一次处理包含类类型指针的向量向量)
答案 0 :(得分:1)
仅当i
设置为1
时,才会填充嵌套向量的条目。但无论如何,您都尝试访问其元素[0][0]
。 i
不是1
时,您的界限不受限制。
答案 1 :(得分:1)
您的代码中存在许多问题,并且与糟糕的样式和格式相结合使调试变得不那么有趣。
Binary_Tree treeDummy(d);
tree = treeDummy;
tempVec.push_back(&tree);
我不确定你在这里尝试做什么,但上面看起来不对。您正在将treeDummy的数据复制到树上。您将丢失指向子节点树的链接。之后,您将同一个树实例推送到临时向量中。这意味着向量中的所有元素最终都指向tree
中的局部变量main
。因此,即使没有发生段错误,您也会遇到别名问题,因为它们都引用相同的tree
对象,而不是单独的BinaryTree
实例。
vector< vector<Binary_Tree*> >::iterator itr=vec.begin()+(lev+1);
vec.erase(itr);
vec.insert(itr,tempVec);
在BinaryTree::insert_node
执行未定义的行为后,您的erase
正在使用无效的迭代器。
childNum = set_childNum(vec[lev][sib-1]);
// ...
prev = vec[lev][sib];
以上内容可以访问向量中的越界索引。例如。您推送tempVec
只包含1个元素,然后使用insert_node
= 1来调用sib
。
// ...
if(x == 5)
{
cout<<endl<<endl;
goto here;
}
此处也完全没有goto
的使用,应该使用传统的while循环来替换condition != 5
。
然而,程序中的更高级别问题是其设计中没有明确的约束和不变量。每个功能需要有哪些假设和先决条件?为什么在类本身应该处理它时使用向量来保存BinaryTree
个节点。你应该首先整理整体设计,否则你只会在其他错误出现的时候玩w鼹鼠。