2016-11-20 71 views
0

我想用Hackerrank(https://www.hackerrank.com/challenges/self-balancing-tree)使用它们的编辑器解决这个问题。以下是C++函数的代码,我写道:AVL树插入 - 分段错误

node* makeNewNode (int data) 
{ 
    node* temp= new node(); 
    temp->val=data; 
    temp->left=NULL; 
    temp->right=NULL; 
    temp->ht=0; 
    return temp; 
} 

//------------------------------------------------------------ 
int height(node* temp) 
{ 
    if(temp==NULL) 
     return -1; 
    return temp->ht; 
} 

//------------------------------------------------------------ 
int balanceFactor(node* root) 
{ 
    if(root==NULL) 
     return 0; 
    return height(root->left)-height(root->right); 
} 

//------------------------------------------------------------ 
node* rightrotation(node* root) 
{ 
    node* temp1 = root->left; 
    node* temp = temp1->right; 
    temp1->right = root; 
    root->left = temp; 
    root->ht = max(height(root->left), height(root->right)) + 1; 
    temp1->ht = max(height(temp1->left), height(temp1->right)) + 1; 
    return temp1; 
} 

//------------------------------------------------------------ 
node* leftrotation(node* root) 
{ 
    node* temp = root->right; 
    node* temp1 = temp->left; 
    temp->left = root; 
    root->right = temp1; 
    root->ht = max(height(root->left), height(root->right)) + 1; 
    temp->ht = max(height(temp->left), height(temp->right)) + 1; 
    return temp; 
} 

//------------------------------------------------------------ 
node* insert(node* root, int data) 
{ 
    if(root == NULL) 
     return makeNewNode(data); 

    if(data<root->val) 
     root->left = insert(root->left, data); 
    else if(data>root->val) 
     root->right = insert(root->right, data); 
    else 
     return root; 

    root->ht = 1 + max(height(root->left), height(root->right)); 
    int balance = balanceFactor(root); 

    if(data<root->left->val && balance>1) 
     return rightrotation(root); 

    if(data>root->right->val && balance<-1) 
     return leftrotation(root); 

    if(balance>1 && data > root->left->val) 
    { 
     root->left = leftrotation(root->left); 
     return rightrotation(root); 
    } 

    if(balance<-1 && data < root->right->val) 
    { 
     root->right = rightrotation(root->right); 
     return leftrotation(root); 
    } 

    return root; 
} 

我得到分割故障线路if(balance>1 && data > root->left->val)但我想不出为什么。在尝试之前,我尝试了root->left的支票是null,但即使这样也是给了seg故障。

因为我使用Hackerrank内置编辑器,主要功能是照顾。

然而,为了调试的目的,我添加了下面的main():

int main() 
{ 
node* root=NULL; 
root=insert(root,1); 
root=insert(root,2); 
root=insert(root,3); 
return 0; 
} 

我试过网上GDB(www.onlinegdb.com),它显示

Program received signal SIGSEGV, Segmentation fault.                      
0x0000000000400aa2 in insert (root=0x603010, data=2) at main.cpp:86                  
86   if(data<root->left->val && balance>1)  

请帮助。

+2

使用正确的工具来解决这些问题是你的调试器。在*堆栈溢出问题之前,您应该逐行执行您的代码。如需更多帮助,请阅读[如何调试小程序(由Eric Lippert撰写)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。至少,您应该\编辑您的问题,以包含一个[最小,完整和可验证](http://stackoverflow.com/help/mcve)示例,该示例再现了您的问题,以及您在调试器。 –

+0

上面的大致意思是:_“你能否在'main()'中包括你所做的事情,并且只在上面的代码中留下疑似有问题的函数,以便我们可以重现并确认你的错误?”_ – Ziezi

回答

1

你不能写

if(data<root->left->val && balance>1) 

如果root或者root->left可以nullptr

如果您的AVL树只有一个根,并且您正在插入正确的节点,则root->left == nullptrroot->right是您的插入节点。

因此,执行将继续执行data < root->left->val,并且会产生分段错误。你需要插入多个条件像

if(root->left != nullptr && data<root->left->val && balance>1) 

下面是改进的插件功能:

node* insert(node* root, int data) 
{ 
    ... 
    int balance = balanceFactor(root); 

    if(root->left && data<root->left->val && balance>1) // here was the segmentation fault with gdb 
     return rightrotation(root); 

    if(root->right && data>root->right->val && balance<-1) 
     return leftrotation(root); 

    if(balance>1 && root->left && data > root->left->val) 
    { ... } 

    if(balance<-1 && root->right && data < root->right->val) 
    { ... } 

    return root; 
} 
+0

我已经试过了,它没有帮助。我在问题的细节中提到过它。 – Bharg

+0

@Bharg我试过你的主要与gdb和唯一的错误是条件'root-> left!= NULL'在'if'中缺少。有了这个条件,你的程序就结束了。 – Franck

+0

对不起,我的坏。我没有在所有四个轮换条件中添加该检查,但只有两个。谢谢! – Bharg