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

Sample Implementation of Binary Trees doesn't work for large number of values

本文关键字:适用于 不适用 实现 二叉树      更新时间:2023-10-16

我最近试图实现一个二值树,它似乎工作小于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);

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

您的堆栈溢出来自您的findLast方法,一旦二叉树变得太大,递归就会变得太多,并在某一点上溢出调用堆栈。你应该把它转换成一个非递归的方法,把搜索信息存储在某种结构中,并动态地分配,这样你的堆栈就不会被填满。

p。如果在c++中使用new而不是mallocdelete来清除分配的内存,您当前正在泄漏内存

迭代版本:

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;
    }
}

这不是一个真正的答案。我只是想建议一个代码更改,作为原始代码的附录,并附上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;
        }
    }
}
相关文章: