简体   繁体   English

在C中插入二进制搜索树

[英]insertion binary search tree in C

I've been stuck on the insertion part of the binary search tree. 我一直被困在二进制搜索树的插入部分。 I get so confused with nested structs. 我对嵌套结构感到困惑。 The basic idea of this program is to create a bst that is able to hold names and double values which get stored by value (obviously). 该程序的基本思想是创建一个bst,它可以保存按值存储的名称和双精度值(显然)。

Example: I want to store 示例:我要存储

Jane 3.14 简3.14

John 3.233 约翰3.233

Luke 6.4 路加福音6.4

Mike 1.4 迈克1.4

so the bst would look like 所以bst看起来像

                 3.14
                 /   \
              1.4    3.233
                       \
                        6.4

however I'm having trouble with the insertHelper recursion portion of the code. 但是我在代码的insertHelper递归部分遇到了麻烦。 The hash table is a bonus part of the code that I'll try implementing at a later time. 哈希表是我稍后将尝试实现的代码的重要部分。 Thank you for your help! 谢谢您的帮助!

typedef struct name_val // holds name and value
{
    char *name;
    double value;
}NAME_VAL;

typedef struct node //binary search tree
{
    NAME_VAL *nV;
    struct node *left;
    struct node *right;
}NODE;

struct tmap_struct  //handle for bst and hashtable
{
    int nL; //nodes on left
    int nR; //nodes on right
    NODE *root;
    NODE **table;
};


int tmap_insert(TMAP_PTR hashTree, char * name, double val)
{
    if(hashTree->root == NULL)
    {
        NODE *bst = (NODE *)malloc(sizeof(NODE));
        NAME_VAL *root = (NAME_VAL *)malloc(sizeof(NAME_VAL));
        bst->nV = root;
        bst->nV->value = val;
        strcpy(bst->nV->name, name);
        hashTree->root = bst;
        hashTree->nL = 0;
        hashTree->nR = 0;
    }

    else 
        insertHelper(hashTree->root, val, name);

}

void insertHelper(TMAP_PTR hashTree, int val, char * name)
{
    if(val < hashTree->root->nV->value)
    {
        if(hashTree->root->left == NULL)
        {
            hashTree->root->left = (NODE *)malloc(sizeof(NODE));
            hashTree->root->left->nV = (NAME_VAL *) malloc(sizeof(NAME_VAL));
            strcpy(hashTree->root->left->nV->name, name);
            hashTree->root->nV->value = val;
            (hashTree->nL)++;
        }

        else
            insertHelper(hashTree->root->left, val, name);
    }

    else
    {
        if(hashTree->root->right == NULL)
        {
            hashTree->root->right = (NODE *)malloc(sizeof(NODE));
            hashTree->root->right->nV = (NAME_VAL *)malloc(sizeof(NAME_VAL));
            strcpy(hashTree->root->left->nV->name,name);
            hashTree->root->nV->value = val;
            (hashTree->nR)++;
        }

        else
            insertHelper(hashTree->root->right, val, name);
    }
}

I doubt this compiles. 我怀疑这会编译。 Is that the problem you're having? 那是你的问题吗?

From what I can see, you have declared insertHelper with the wrong type for its first parameter. 从我所看到的,您已经为insertHelper的第一个参数声明了错误的类型。 It should take NODE* values, not TMAP_PTR values. 它应该采用NODE*值,而不是TMAP_PTR值。 That's because you always call it with nodes out of your tree. 那是因为您总是使用树外的节点来调用它。

So the first part of the function should look like this: 因此,函数的第一部分应如下所示:

void insertHelper(NODE *node, int val, char * name)
{
    if(val < node->nV->value)
    {
        if(node->left == NULL)
        {
            node->left = (NODE *)malloc(sizeof(NODE));
            node->left->nV = (NAME_VAL *) malloc(sizeof(NAME_VAL));
            strcpy(node->left->nV->name, name);
            node->left->nV->value = val;
        }

        else
            insertHelper(node->left, val, name);
    }

    //.....

Note that I removed the line: 请注意,我删除了这一行:

(hashTree->nR)++;

It hardly even makes sense to track this information, unless maybe you do it at the node level. 除非您可能在节点级别进行跟踪,否则甚至根本没有必要跟踪此信息。

But if you must, you could have insertHelper recursively return a positive or negative value to indicate what side it inserted on. 但是,如果必须这样做,可以让insertHelper递归地返回一个正值或负值,以指示它插入insertHelper一侧。 But that doesn't makes sense. 但这没有道理。 What is it on the right of? 右边是什么? You may have inserted it on the right of a node that was in the left half of the tree. 您可能已将其插入到树的左半部分中的节点的右侧。

If you store this information on each node, you can recursively update the node above as you return from insertHelper . 如果将此信息存储在每个节点上,则可以在从insertHelper返回时递归更新上述节点。 Maybe that's what you were trying to do. 也许这就是您想要做的。 Balanced tree implementations do something similar - AVL trees store the maximum depth of the tree at a node and use that to do branch rotations for rebalancing. 平衡树的实现与之类似-AVL树在节点处存储树的最大深度,并使用该深度进行分支旋转以进行重新平衡。

You'll have to adapt mine(It's almost standard C besides the unneeded template and class), but it's a similar algorithm: (I believe, I didn't look at any source for my own purposes.) 您必须改编我的(除了不需要的模板和类之外,它几乎是标准的C),但这是一个类似的算法:(我相信,出于我自己的目的,我没有看任何源代码。)

template<typename T>
class BST {
    protected:
        typedef struct node_t {
            struct node_t * dir[2];
            T data; 
        } node;

        node * root;

        void insert_node(node * active_node, T data){ //call with node *root;
            int next = data < active_node->data ? 0 : 1;
            if(active_node->dir[next] == NULL){
                active_node->dir[next] = new node;
                active_node->dir[next]->dir[0] = NULL;
                active_node->dir[next]->dir[1] = NULL;
                active_node->data = data;
            } else
                insert_node(active_node->dir[next], data);
        }

    public:
        BST() : root(new node){root->dir[0] = NULL; root->dir[1] = NULL; root->data = 0;}
       ~BST(){}
} 

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

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