[英]getting segmentation fault in searching an element in binary search tree in c++
node ** BST :: searchElement(node **tree, int item)
{
if( ((*tree)->data == item) || ( (*tree) == NULL) )
return tree;
else if( item < (*tree)->data)
return searchElement( &(*tree)->left, item);
else
return searchElement( &(*tree)->right, item);
}
int main(){
BST obj;
int choice;
int height=0,total=0,n,item;
node **tmp;
system("cls");
while(1){
//clrscr();
cout<<"*****BINARY SEARCH TREE OPERATIONS*****\n\n";
cout<<"1) Create Tree\n";
cout<<"2) Traversal\n";
cout<<"3) Insert Node\n";
cout<<"4) Search Node\n";
cout<<"5 Find Smallest Node\n";
cout<<"6) Find Largest Node\n";
cout<<"7) Exit\n";
cout<<"Enter your choice : ";
cin>>choice;
switch(choice){
case 1 : //Create Tree
cout<<"\n\n--Creating Tree--";
cout<<"\nHow many nodes u want to enter : ";
cin>>n;
for(int i=0;i<n;i++){
cout<<"Enter value : ";
cin>>item;
obj.createTree(&obj.tree,item);
}
break;
case 2 : //All Traversals
cout<<"\n\nInorder Traversal : ";
obj.inOrder(obj.tree);
cout<<"\n\nPre-order Traversal : ";
obj.preOrder(obj.tree);
cout<<"\n\nPost-order Traversal : ";
obj.postOrder(obj.tree);
getch();
break;
case 3 : //Inserting a node in a tree
cout<<"\n\n--Inserting Node in a tree--\n";
cout<<"Enter value : ";
cin>>item;
obj.createTree(&obj.tree,item);
cout<<"\nItem is inserted\n";
getch();
break;
case 4 : //Search element
cout<<"\n\n--Search Element--\n";
cout<<"Enter item to searched : ";
cin>>item;
&(*tmp) = obj.searchElement(&obj.tree,item);
if( (*tmp) == NULL)
cout<<"\nSearch Element was not Found";
else
cout<<"\nSearch Element was Found";
getch();
break;
case 5 : //Find Smallest Node
cout<<"\n\nSmallest Node is : ";
obj.findSmallestNode(obj.tree);
getch();
break;
case 6 : //Find Largest Node
cout<<"\n\nLargest Node is : ";
obj.findLargestNode(obj.tree);
getch();
break;
case 7: exit(1);
}//end of switch
}
}
在上面的程序中,當我嘗試在樹中查找特定元素時,只有情況4無法正常工作。 我已經在主程序頂部包括了搜索元素成員函數。 當我調試程序時,我在搜索元素成員函數中遇到分段錯誤,尤其是在if條件下。 我真的不知道該怎么辦才能解決這個問題。 誰能幫我找出搜索元素成員函數內部發生分段錯誤的原因。 如果您對此程序有任何疑問,請告訴我。
if( ((*tree)->data == item) || ( (*tree) == NULL) )
應該
if ( ( (*tree) == NULL) || ((*tree)->data == item) )
如果*tree
實際上為 null,則在第一次檢查時將引用空指針。 交換它們將確保檢查(*tree)->data
時*tree
不為NULL-由於短路評估
另外, &(*tmp)
應該寫成tmp
您正在取消引用未初始化的指針(tmp)。 您應該為此分配內存,或者只是跳過它的使用(我真的不知道為什么在這里需要一個臨時的NODE **。)
這里有一些批評:
由於您僅搜索節點,因此不需要指針到指針。 唯一需要指針的指針是在實際需要修改參數時。 另外,由於您使用的是C ++,因此應該傳遞引用:node *&tree,而不是傳遞pp。 這樣一來,您就可以使用tree變量而不必取消引用它,因為編譯器會為您處理。
在if語句中,您不會檢查左指針或右指針是否為空指針。 我不確定是否為此使用了哨兵節點,但是我假設您沒有。 這樣,我將您的方法更改為:
node * BST :: searchElement(node *tree, int item)
{
if(tree->data == item)
return tree;
//short circuit if statements
else if( (tree->left != NULL) && (item < tree->data) )
return searchElement( tree->left, item );
else if( (tree->right != NULL) && (item > tree->data) ) //>= for duplicates
return searchElement( tree->right, item );
return NULL; //if it isn't found
}
是。 確實,正如Erik已經發布的那樣,您必須寫
if ( ( (*tree) == NULL) || ((*tree)->data == item) )
代替
if( ((*tree)->data == item) || ( (*tree) == NULL) )
因為如果item
尚未在樹中,則在嘗試取消引用NULL指針時,您的代碼肯定會導致segfault。
還有另一個(不太明顯)的問題-絕對不必要的遞歸。 如果在插入或刪除樹節點時未進行仔細的平衡,則樹的高度最多為線性,因此遞歸深度最多為線性,這很容易導致堆棧溢出。 因此,您應該將searchElement
函數轉換為
node** BST::searchElement( node** tree, int item )
{
while( ( (*tree) != NULL) && ( (*tree)->data != item ) )
{
if( item < (*tree)->data )
{
tree = &(*tree)->left;
}
else
{
tree = &(*tree)->right;
}
}
return tree;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.