0
#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;
  }


}

主文件

#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> vec 中的对象传递给实现中的函数(我是 Stl 的新手,第一次处理包含指向类的指针的向量向量类型)

4

2 回答 2

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];

以上可以访问向量中的越界索引。例如。你 push_back atempVec里面只有 1 个元素,然后insert_nodesib= 1 调用。

 // ...
 if(x == 5)
 {
   cout<<endl<<endl;
   goto here;
 }

这里也完全不需要使用goto,应该用传统的 while 循环来检查condition != 5.

但是,您的程序中更高级别的问题是其设计中没有明确的约束和不变量。这些功能中的每一个都需要哪些假设和先决条件才能起作用?BinaryTree当类本身应该处理它时,为什么要使用向量来保存节点。您应该首先整理出整体设计,否则您只会在其他错误出现时玩打地鼠。

于 2013-09-07T02:06:26.850 回答
1

i嵌套向量的条目仅在设置为时才被填充1。但是您无论如何都尝试访问它的元素[0][0]i当is not时,您拥有越界访问权限1

于 2013-09-06T22:57:41.520 回答