我一直试图解决这个问题将近3天没有运气。我试图将大量(500万)无符号整数的元素插入到二叉树中。
当我将要插入的元素限制为10K时,此代码可以正常工作,但是,当我将总元素设置为500万时,它不起作用。 我在我的PC上运行此代码,其中包含:
任何帮助都会非常感激。提前致谢 :) 这是我的代码:
#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);
}
任何帮助都会非常感激。在此先感谢:)
答案 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()
获取随机数或更复杂且确定的随机数生成器。