二叉树的示例实现不适用于大量值

时间:2016-10-07 11:26:13

标签: c++ c algorithm data-structures

我最近试图实现一个二叉树,它似乎工作不到1000个值,但在那之后它最终给了我堆栈溢出错误

#include<iostream>
#include<math.h>

using namespace std;
struct Node{
    long long int val;
    Node *left;
    Node *right;
};
struct BinaryTree{
    Node *head  = (Node*) malloc(sizeof(Node));
    bool headSet = false;
    Node* findLast(Node *asgn,int val){
        if (val > asgn->val){
            if (asgn->right != NULL)
                asgn  = findLast(asgn->right, val);
            else
                return asgn;
        }
        else{
            if (asgn->left != NULL)
                asgn = findLast(asgn->left, val);
            else
                return asgn;
        }
        return asgn;
    }
    void insert(long long int vals){
        if (headSet){
            Node *asgn = (Node*) malloc(sizeof(Node));
            asgn = findLast(head,vals);
            Node *fix = (Node*)malloc(sizeof(Node));
            fix->val = vals;
            fix->left = NULL;
            fix->right = NULL;
            if (vals > asgn->val){
                asgn->right = fix;
                asgn->left = NULL;
            }
            else{
                asgn->right = NULL;
                asgn->left = fix;
            }
        }
        else{
            head->val = vals;
            head->right = NULL;
            head->left = NULL;
            headSet = true;
        }
    }
};
int main(){
    BinaryTree a;
    for (long long int i = 0; i < 100;i++)
    a.insert(i);

    return 0;
}

例如: - 如果我改变

for (long long int i = 0; i < 100;i++)
    a.insert(i);

for (long long int i = 0; i < 10000;i++)
    a.insert(i);

它给了我错误。我似乎无法理解为什么会发生这种情况,堆栈溢出?

3 个答案:

答案 0 :(得分:3)

您的堆栈溢出来自您的findLast方法,一旦二叉树变得太大,递归变得太多并且在一个点上溢出调用堆栈。您应该将它转换为非递归方法,方法是在某种结构中存储有关搜索的信息,并动态分配,以便您的堆栈不会填满。

P.S在C ++中使用new而不是malloc,在delete中使用$( ".editTodo" ).on('click',(function() { console.log( $(this) ); }); 来清理分配的内存,你当前正在泄漏内存。

答案 1 :(得分:2)

迭代版本:

Node* findLast(Node *asgn,int val){
  while (1)
  {
    if (val > asgn->val) {
      if (asgn->right != NULL)
        asgn = asgn->right;
      else
        return asgn;
    }
    else {
      if (asgn->left != NULL)
        asgn = asgn->left;
      else
        return asgn;
    }
  }
}

很简单,不是吗?

insert的更正版本:

void insert(long long int vals){
   if (headSet){
       // Node *asgn = (Node*) malloc(sizeof(Node));   // removed
       Node *asgn = findLast(head,vals);               // line changed slighty
       Node *fix = (Node*)malloc(sizeof(Node));
       fix->val = vals;
       fix->left = NULL;
       fix->right = NULL;

       if (vals > asgn->val){
           asgn->right = fix;
            //asgn->left = NULL;     // removed
       }
       else{
           //asgn->right = NULL;     // removed
           asgn->left = fix;
        }
    }
    else{
        head->val = vals;
        head->right = NULL;
        head->left = NULL;
        headSet = true;
    }
}

答案 2 :(得分:1)

这不是一个答案。我只想建议将代码更改作为Michael Walz更正的原始代码的附录。我的建议是省略headSet成员并将head成员初始化为NULL,并在第一次插入时分配head,如下所示:

struct BinaryTree{
    Node *head  = (Node *)NULL;
    Node* findLast(Node *asgn,int val){ // Courtesy of Michael Walz
        while (1){
            if (val > asgn->val){
               if (asgn->right != NULL)
                   asgn = asgn->right;
               else
                   return asgn;
            }
            else{
                if (asgn->left != NULL)
                    asgn = asgn->left;
                else
                    return asgn;
            }
        }
    }
    void insert(long long int vals){
        Node *fix = (Node*)malloc(sizeof(Node));
        fix->val = vals;
        fix->left = NULL;
        fix->right = NULL;
        if (head != NULL){
            Node *asgn = findLast(head,vals);
            if (vals > asgn->val){
                asgn->right = fix;
            }
            else{
                asgn->left = fix;
            }
        }
        else{
            head = fix;
        }
    }
}