在 C++ 中创建两个不同的二叉树时出现分段错误

segmentation fault when creating two different Binary trees in c++

本文关键字:二叉树 错误 分段 两个 创建 C++      更新时间:2023-10-16
#include<iostream>
using namespace std;
struct tree
{
int data;
struct tree *leftchild;
struct tree *rightchild;
};
typedef struct tree* Binary_tree;
//this function Creates a new node and assigns memory to it 
Binary_tree CreateNode(int value)
{
Binary_tree temp;
temp = new struct tree;
temp->data = value;
temp->leftchild = NULL;
temp->rightchild = NULL;
return temp;
}

//this function links nodes with each other
Binary_tree AddNode(Binary_tree head,int value)
{
Binary_tree temp = head;
if(head == NULL)
{
Binary_tree newNode = CreateNode(value);
head = newNode;
}
else if(head->leftchild == NULL)
{
Binary_tree newNode = CreateNode(value);
temp->leftchild = newNode;
}
else
{
Binary_tree newNode = CreateNode(value);
temp->rightchild = newNode;
}
return head;
}

void PrintTree(Binary_tree head)
{
if(head == NULL)
exit;
else
{
Binary_tree temp = head;
cout<<temp->data<<endl<<temp->leftchild<<"tt"<<temp<<endl<<temp->rightchild<<endl;
PrintTree(temp->leftchild);
PrintTree(temp->rightchild);
}
}

int main()
{
Binary_tree head,second;
for(int i=1;i<12;i++)
{
head = AddNode(head,i);
second = AddNode(second,i+2);
}
PrintTree(head);
PrintTree(second);
}

我得到的错误是分段错误。 只有当我创建 2 棵树(即头和秒(时,它才会出现。 当我只处理头树时,它工作正常,我不明白是什么导致了错误。

我认为分段错误是因为将这些树相邻地存储在内存中,但树是非线性的,所以这应该不是问题,有人可以说出问题所在吗

这是用 c++ 重写的程序。

我使用了最佳实践,例如使用 RAII 来保持状态,而不是手动摆弄指针和新建/删除,安排默认初始化的对象等。

一个功能上的区别是我的树是非平衡的二叉搜索树。 您的树木在 3 个节点后停止生长。

您会注意到,使用这些技术的代码实际上更简单。

#include <iostream>
#include <memory>
struct tree;
using Tree = std::unique_ptr<tree>;
struct tree
{
int data = 0;
Tree left;
Tree right;
};
//this function Creates a new node and assigns memory to it 
Tree CreateNode(int value)
{
Tree retval = std::make_unique<tree>();
retval->data = value;
return retval;
}
//this function links nodes with each other
Tree AddNode(Tree head, int value)
{
if(!head)
{
return CreateNode(value);
}
if (head->data <= value)
{
head->right = AddNode( std::move(head->right), value );
return head;
}
head->left = AddNode( std::move(head->left), value );
return head;
}

void PrintTree(Tree const& head, int indent = 0)
{
if(!head)
return;
auto do_indent = [indent]{
for (int i = 0; i < indent; ++i)
std::cout << "t";
};
do_indent();
std::cout << head->data << std::endl;
//do_indent();
//std::cout << head->left.get() << "tt" << head.get() << std::endl;
//do_indent();
//std::cout << head->right.get() << std::endl;
PrintTree(head->left, indent+1);
PrintTree(head->right, indent+1);
}

int main()
{
Tree head,second;
for(int i=1;i<12;i++)
{
head = AddNode(std::move(head),i);
second = AddNode(std::move(second),6+(i+2)%6);
}
PrintTree(head);
PrintTree(second);
}

代码的直接问题是它使用了未初始化的内存;读取未初始化的内存可能会崩溃或不崩溃取决于运气。 它也泄漏了,实际上并没有建造你要求的树。

打印这些树的一个有趣方法是:

void PrintTree(Tree const& head, int indent = 0)
{
auto do_indent = [indent]{
for (int i = 0; i < indent; ++i)
std::cout << "t";
};
if(!head)
{
do_indent();
std::cout << "." << std::endl;
return;
}
PrintTree(head->left, indent+1);
do_indent();
std::cout << head->data << std::endl;
PrintTree(head->right, indent+1);
}

我们首先向左打印,然后向头打印,然后向右打印。 这看起来更像是一棵树,而空树的单个.

这将生成输出:

.
1
.
2
.
3
.
4
.
5
.
6
.
7
.
8
.
9
.
10
.
11
.
.
6
.
6
.
7
.
7
.
8
.
9
.
9
.
10
.
10
.
11
.
11
.

活生生的例子。