将数百万个元素插入二进制搜索树BST

时间:2015-12-06 22:58:39

标签: c tree binary-search-tree

我一直试图解决这个问题将近3天没有运气。我试图将大量(500万)无符号整数的元素插入到二叉树中。

当我将要插入的元素限制为10K时,此代码可以正常工作,但是,当我将总元素设置为500万时,它不起作用。 我在我的PC上运行此代码,其中包含:

  • Windows 7 - 32
  • RAM 4 GB

任何帮助都会非常感激。提前致谢 :) 这是我的代码:

#include<stdlib.h>
#include<stdio.h>

typedef int ElementType;

typedef struct TreeNode {
  ElementType element;
  struct TreeNode *left, *right;
} TreeNode;

TreeNode *createTree(){
    //Create the root of tree
    TreeNode *tempNode;
    tempNode = malloc(sizeof(TreeNode));
    tempNode->element = 0;
    tempNode->left = NULL;
    tempNode->right = NULL;
    return tempNode;
}

TreeNode *createNode(ElementType X){
    //Create a new leaf node and return the pointer
    TreeNode *tempNode;
    tempNode = malloc(sizeof(TreeNode));
    tempNode->element = X;
    tempNode->left = NULL;
    tempNode->right = NULL;
    return tempNode;
}

TreeNode *insertElement(TreeNode *node, ElementType X){
    //insert element to Tree
    if(node==NULL){
        return createNode(X);
    }
    else{
        if(X < node->element){
                node->left = insertElement(node->left, X);
                return node; // add this.
}
    else if(X > node->element){
                 node->right =  insertElement(node->right, X);
                 return node; // add t

        else if(X == node->element){
            printf("Oops! the element is already present in the tree.");
        }
    }
}

TreeNode *displayTree(TreeNode *node){
    //display the full tree
    if(node==NULL){
        return;
    }
    displayTree(node->left);
    printf("| %d ", node->element); 
    displayTree(node->right);
}

main(){
    //pointer to root of tree #2
    TreeNode *TreePtr;
    TreeNode *TreeRoot;
    TreeNode *TreeChild;

    //Create the root of tree
    TreePtr = createTree();

    TreeRoot = TreePtr;

    TreeRoot->element = 32;
    
  for ( int i=0; i < 5000000; i ++)
    insertElement(TreeRoot, i);
   
    displayTree(TreeRoot);
}

任何帮助都会非常感激。在此先感谢:)

2 个答案:

答案 0 :(得分:2)

假设你的代码中没有其他错误,总是插入8会将树退化为一个列表,我认为,你的堆栈会在远低于500万的递归级别上溢出。

为了避免退化的树,我建议你使用AVL树的插入/删除语义。 这样做的好处是,您的数据结构可以保持原样,但您只需调整插入和删除过程。

编辑:在您的评论中,您现在声明您不会插入总是8但是我。这意味着,您将预先排序的元素插入到二叉树中,这也将其退化为列表,因此出现与始终插入“8”相同的问题。

看起来像:

1
 \
  2
   \
    3
     \
      4
       \
       ...

按顺序插入元素后。 AVL-Tree不会遇到这个问题: https://en.wikipedia.org/wiki/AVL_tree

答案 1 :(得分:1)

好的费萨尔。

如果插入i的值,则始终会插入一个大于当前树中包含的所有键的键。因此,您将得到一个最大高度的树,其性能(和形状)相当于一个列表。由于算法是递归的,因此很快就会出现堆栈溢出。

处理问题的一种可能方法是插入随机密钥,但不能保证避免溢出。从理论上讲,在不成功的搜索中修改的节点数的平均值是O(log N)。

因此,您可以使用rand()获取随机数或更复杂且确定的随机数生成器。