分段错误(核心已转储)- 线程二进制搜索树
Segmentation fault (core dumped) - Threaded Binary Search Tree
我不断收到以下错误:分段错误(核心已转储)。我找出了导致问题的代码行(在程序中标有注释)。请告诉我为什么会出现此错误以及如何解决它。
我已经尝试干燥 运行 我的代码(在纸上)并且没有发现任何逻辑错误(根据我的理解)。
我最近才开始接触编码和 Whosebug,请指导我如何进一步改进我的问题以及我的代码。谢谢!
class tree
{
struct node // Creates a node for a tree
{
int data;
bool rbit,lbit; // rbit/lbit= defines if right/left child of root is present or not
node *left,*right;
};
public:
node *head,*root;
tree() // constructor initializes root and head
{
root=NULL;
head=createnode(10000);
}
node *createnode(int value)
{// Allocates memory for a node then initializes node with given value and returns that node
node *temp=new node ;
temp->data=value;
temp->lbit=0;
temp->rbit=0;
temp->left=NULL;
temp->right=NULL;
return temp;
}
void insert(node *temp,int value) // Creates binary search tree node by node
{
if(root==NULL) // Checking if tree is empty
{
root=createnode(value); //Root now points to new memory location
head->left=root;
head->lbit=1;
root->left=head;//this line gives the segmentation fault (what i thought before correction)
}
}
void inorder(node *root) // Inorder traversal of tree (this function is logically incorrect)
{
if(root==NULL)
return;
inorder(root->left);
cout<<root->data<<"\t";
inorder(root->right);
}
void getdata()//Accepts data , creates a node through insert() , displays result through inorder()
{
int data;
cout<<"Enter data"<<endl;
cin>>data;
insert(root,data);
inorder(root);
}
/*void inorder(node *root) // Working inorder code
{
if(root->lbit==1)
inorder(root->left);
cout<<root->data<<"\t";
if(root->rbit==1)
inorder(root->right);
}*/
};
int main()
{
tree t; // Tree Object
t.getdata(); // Calling getdata
return 0;
}
没有足够的信息来确切说明它应该如何工作(例如 node.lbit
是什么)。
问题的insert()
功能将无法使用。它传递的值会立即被覆盖(除其他问题外)。没有解释 tree.head
的用途,因此被忽略。字段 node.lbit
和 node.rbit
看起来是 node.left != NULL
的多余标志(右边也类似)。这些也省略了。 insert()
也没有正确创建树。
void insert(int value) // Insert a value into the tree (at branch)
{
// Create a new node to insert
struct node *temp = createnode(value);
if (root == NULL) // Checking if tree is empty
{
root = temp; //Root now points to temp
}
else
{
insertAtBranch(root, temp);
}
}
// recursively find the leaf-node at which to insert the new node
void insertAtBranch(node *branch, node *new_node)
{
// to create a BST, less-than go left
if (new_node->value <= branch->value)
{
if (branch->left == NULL)
branch->left = new_node; // There's no left-branch, so it's the node
else
insertAtBranch(branch->left, new_node); // go deeper to find insertion point
}
else // greater-than go right
{
if (branch->right == NULL)
branch->right = new_node;
else
insertAtBranch(branch->right, new_node);
}
}
想象一下二叉树是如何工作的。新节点只会插入到边缘。所以你查看一个给定的节点,并决定这个新节点是小于还是大于你正在查看的节点(当然,除非树是空的)。
假设 new-node.value
小于 branch-node.value
,您想向左分支。还是同一个节点,如果没有左分支(node.left == NULL)
,新节点就是左分支。否则,您需要沿着左分支向下行驶并再次检查。
我会将 node
设为 class,并使用构造函数至少设置默认属性和 value
。但这没什么大不了的。
我认为评论部分在很大程度上反映了沟通不畅。很容易相信您正在经历 ON 特定线路的崩溃。
实际情况并非如此。相反,您所做的是在树中创建一个循环,该循环导致 inorder
函数无限递归。这会导致出现段错误的堆栈溢出——如果您的程序只是 运行 附加了调试器(例如 gdb),这将非常容易发现。
temp = createnode(value);
if(root == NULL)
{
root = temp;
head->left = root;
head->lbit = 1;
temp->left = head;
}
查看您刚刚创建的循环:
head->left points to root
root->left == temp->left, which points to head
中序遍历现在将访问:
root
head
root
head
root
head
...
因为它永远不会到达左分支的末尾,所以该函数在溢出堆栈和崩溃之前不会输出任何内容。
所以不,您的代码在逻辑上不正确。它有一个基本的设计缺陷。您需要重新考虑在树中存储的内容以及原因。
来自代码,
root=temp; //Root now points to temp
head->left=root;
head->lbit=1;
temp->left=head;// this line gives the segmentation fault
root 没有指向 temp。 temp(pointer) 被分配给 root(pointer)。
head的左指针是root,temp的左指针是head(也就是说root的左指针是head)。所以在函数 "inorder",
void inorder(node *root) // Inorder traversal of tree
{
if(root==NULL) <<<<<<
return;
inorder(root->left);
cout<<root->data<<"\t";
inorder(root->right);
}
参数节点 *root(左)永远不会为 NULL,并且函数永远不会 return。
我不断收到以下错误:分段错误(核心已转储)。我找出了导致问题的代码行(在程序中标有注释)。请告诉我为什么会出现此错误以及如何解决它。
我已经尝试干燥 运行 我的代码(在纸上)并且没有发现任何逻辑错误(根据我的理解)。
我最近才开始接触编码和 Whosebug,请指导我如何进一步改进我的问题以及我的代码。谢谢!
class tree
{
struct node // Creates a node for a tree
{
int data;
bool rbit,lbit; // rbit/lbit= defines if right/left child of root is present or not
node *left,*right;
};
public:
node *head,*root;
tree() // constructor initializes root and head
{
root=NULL;
head=createnode(10000);
}
node *createnode(int value)
{// Allocates memory for a node then initializes node with given value and returns that node
node *temp=new node ;
temp->data=value;
temp->lbit=0;
temp->rbit=0;
temp->left=NULL;
temp->right=NULL;
return temp;
}
void insert(node *temp,int value) // Creates binary search tree node by node
{
if(root==NULL) // Checking if tree is empty
{
root=createnode(value); //Root now points to new memory location
head->left=root;
head->lbit=1;
root->left=head;//this line gives the segmentation fault (what i thought before correction)
}
}
void inorder(node *root) // Inorder traversal of tree (this function is logically incorrect)
{
if(root==NULL)
return;
inorder(root->left);
cout<<root->data<<"\t";
inorder(root->right);
}
void getdata()//Accepts data , creates a node through insert() , displays result through inorder()
{
int data;
cout<<"Enter data"<<endl;
cin>>data;
insert(root,data);
inorder(root);
}
/*void inorder(node *root) // Working inorder code
{
if(root->lbit==1)
inorder(root->left);
cout<<root->data<<"\t";
if(root->rbit==1)
inorder(root->right);
}*/
};
int main()
{
tree t; // Tree Object
t.getdata(); // Calling getdata
return 0;
}
没有足够的信息来确切说明它应该如何工作(例如 node.lbit
是什么)。
问题的insert()
功能将无法使用。它传递的值会立即被覆盖(除其他问题外)。没有解释 tree.head
的用途,因此被忽略。字段 node.lbit
和 node.rbit
看起来是 node.left != NULL
的多余标志(右边也类似)。这些也省略了。 insert()
也没有正确创建树。
void insert(int value) // Insert a value into the tree (at branch)
{
// Create a new node to insert
struct node *temp = createnode(value);
if (root == NULL) // Checking if tree is empty
{
root = temp; //Root now points to temp
}
else
{
insertAtBranch(root, temp);
}
}
// recursively find the leaf-node at which to insert the new node
void insertAtBranch(node *branch, node *new_node)
{
// to create a BST, less-than go left
if (new_node->value <= branch->value)
{
if (branch->left == NULL)
branch->left = new_node; // There's no left-branch, so it's the node
else
insertAtBranch(branch->left, new_node); // go deeper to find insertion point
}
else // greater-than go right
{
if (branch->right == NULL)
branch->right = new_node;
else
insertAtBranch(branch->right, new_node);
}
}
想象一下二叉树是如何工作的。新节点只会插入到边缘。所以你查看一个给定的节点,并决定这个新节点是小于还是大于你正在查看的节点(当然,除非树是空的)。
假设 new-node.value
小于 branch-node.value
,您想向左分支。还是同一个节点,如果没有左分支(node.left == NULL)
,新节点就是左分支。否则,您需要沿着左分支向下行驶并再次检查。
我会将 node
设为 class,并使用构造函数至少设置默认属性和 value
。但这没什么大不了的。
我认为评论部分在很大程度上反映了沟通不畅。很容易相信您正在经历 ON 特定线路的崩溃。
实际情况并非如此。相反,您所做的是在树中创建一个循环,该循环导致 inorder
函数无限递归。这会导致出现段错误的堆栈溢出——如果您的程序只是 运行 附加了调试器(例如 gdb),这将非常容易发现。
temp = createnode(value);
if(root == NULL)
{
root = temp;
head->left = root;
head->lbit = 1;
temp->left = head;
}
查看您刚刚创建的循环:
head->left points to root
root->left == temp->left, which points to head
中序遍历现在将访问:
root
head
root
head
root
head
...
因为它永远不会到达左分支的末尾,所以该函数在溢出堆栈和崩溃之前不会输出任何内容。
所以不,您的代码在逻辑上不正确。它有一个基本的设计缺陷。您需要重新考虑在树中存储的内容以及原因。
来自代码,
root=temp; //Root now points to temp
head->left=root;
head->lbit=1;
temp->left=head;// this line gives the segmentation fault
root 没有指向 temp。 temp(pointer) 被分配给 root(pointer)。 head的左指针是root,temp的左指针是head(也就是说root的左指针是head)。所以在函数 "inorder",
void inorder(node *root) // Inorder traversal of tree
{
if(root==NULL) <<<<<<
return;
inorder(root->left);
cout<<root->data<<"\t";
inorder(root->right);
}
参数节点 *root(左)永远不会为 NULL,并且函数永远不会 return。