简体   繁体   English

作业,C中的递归BST插入功能

[英]Homework, Recursive BST insert function in C

This is homework for my first class in c. 这是我上c课的第一堂课。 It focuses on dynamic allocation in c, in the form of a bst. 它专注于以bst形式在c中进行动态分配。

I have to have a dynamically allocated BST, recursively implemented. 我必须有一个动态分配的BST,以递归方式实现。 I know that my traversal works correctly, and am having trouble inserting nodes. 我知道遍历正常,并且在插入节点时遇到问题。 I only ever have the root node, and every other node seems to be set to NULL. 我只有根节点,而每个其他节点似乎都设置为NULL。 I think that I can't print the rest of the nodes when traversing, because I am trying to access the data member of a NULL struct. 我认为遍历时无法打印其余节点,因为我正在尝试访问NULL结构的数据成员。 My code so far is as follows: 到目前为止,我的代码如下:

void insert_node(TreeNode** root, int toInsert){
    if(*root==NULL){
        TreeNode *newnode = (TreeNode *)malloc(sizeof(TreeNode));
        newnode->data = toInsert;
        newnode->left = NULL;
        newnode->right = NULL;
    }
    else if(toInsert > (*root)->data){ //if toInsert greater than current
        struct TreeNode **temp = (TreeNode **)malloc(sizeof(struct TreeNode*));
        *temp = (*root)->right;
        insert_node(temp, toInsert);
    }
    else{ //if toInsert is less than or equal to current
        struct TreeNode **temp = (TreeNode **)malloc(sizeof(struct TreeNode*));
        *temp = (*root)->left;
        insert_node(temp, toInsert);
    }
}

void build_tree(TreeNode** root, const int elements[], const int count){
    if(count > 0){
        TreeNode *newroot = (TreeNode *)malloc(sizeof(TreeNode));
        newroot->data = elements[0];
        newroot->left = NULL;
        newroot->right = NULL;
        *root = newroot;
        for(int i = 1; i < count; i++){
            insert_node(root, elements[i]);
        }
}

I'm sure it's only one of many problems, but I get segmentation faults on any line that uses "(*root)->data", and I'm not sure why. 我确定这只是许多问题之一,但是在使用“(* root)-> data”的任何行上都会出现分段错误,我不确定为什么。

As a side note, despite getting segmentation faults for the "(*root)->data" lines, I'm still able to printf "(*root)->data". 附带说明一下,尽管在“(* root)-> data”行中遇到分段错误,但我仍然能够打印“(* root)-> data”。 How is it possible to print the value, but still get a segmentation fault? 如何打印该值,但仍然出现分段错误?

It's messy. 太乱了 Some things that might help 有些事情可能会有所帮助

1) Don't need to use TreeNode* , pointer to pointer, as argument. 1)不需要使用TreeNode * (指向指针的指针)作为参数。 Use jsut the TreeNode . 使用jsut TreeNode (something went wrong here, as it's some feature from the text editor, consider and additional * after each TreeNode in this line) (这里出错了,因为它是文本编辑器的某些功能,请考虑在此行中的每个TreeNode之后加上*)

2) Not a strict rule, but as best practice avoid using the first node of a linked list to store actual values. 2)不是严格的规则,但是作为最佳实践,请避免使用链接列表的第一个节点来存储实际值。 Use just as the header of your list. 仅用作列表的标题。 Reason is, if you need to delete this node, you don't lose the list. 原因是,如果您需要删除此节点,则不会丢失列表。 Just a tip 只是一个提示

3) In your first function, if *root==NULL, I'd rather make the function fail than adding it to a temporary list (that's being lost in the current code, see that it adds the value to a list that is not being passed outside the function. 3)在您的第一个函数中,如果* root == NULL,我宁愿使函数失败,也不愿将其添加到临时列表中(该函数在当前代码中丢失了,请参见将值添加到不是被传递到函数之外。

4) Well, you are actually making it go to the right if the new value is greater than the node, to the left if it's smaller than the node, but it never stops. 4)好吧,实际上,如果新值大于节点,则实际上使它移到右边,如果新值小于节点,则使它移到左边,但是它永远不会停止。 See this example: Suppose you have the list 1->3->4. 参见以下示例:假设您具有列表1-> 3-> 4。 Now you want to insert 2. What the algorithm will do? 现在您要插入2。该算法将执行什么操作? keep trying to insert in the 1 node and 3 node, switching between them, but never actually inserting anything. 继续尝试在1节点和3节点中插入,在它们之间切换,但不要实际插入任何东西。 Solution: as you will build this list bottom up, your list will always be sorted (inf you insert nodes correctly). 解决方案:在自底向上构建此列表时,将始终对列表进行排序(如果您正确插入了节点)。 So you just need to check if the next node is higher, and if it is, insert right where you are. 因此,您只需要检查下一个节点是否更高,如果更高,请在您要插入的位置正确插入。

5) If you're passing a TreeNode *root as argument (on the 2nd function), you shouldn't have to recreate a new list and make root=newlist. 5)如果要传递TreeNode * root作为参数(在第二个函数上),则不必重新创建新列表并使root = newlist。 Just use the root. 只需使用根即可。 All of this would result in (didn't test, might be some errors): 所有这些都会导致(未测试,可能有一些错误):

void insert_node(TreeNode* root, int toInsert){
if(root==NULL){
    printf("Error");
    return;
}
TreeNode* temp = root; //I just don't like to mess with the original list, rather do this
if(temp->right!=NULL && toInsert > temp->right->data){ //if toInsert greater than next
    insert_node(temp->right, toInsert);
}
else{ //if toInsert is less or equal than next node
    TreeNode* temp2 = temp->right; //grabbing the list after this node
    temp->right=(TreeNode*)malloc(sizeof(TreeNode)); //making room for the new node
    temp->right->right=temp2; //putting the pointer to the right position
    temp->right->left=temp; //setting the left of the next node to the current
    temp->right->data=toInsert;
}
}

void build_tree(TreeNode* root, const int elements[], const int count){
if(count > 0){
    for(int i = 0; i < count; i++){
        insert_node(root, elements[i]);
    }
}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM