将节点添加到二叉搜索树中会随机删除节点

时间:2010-05-09 22:43:46

标签: c data-structures binary-tree

栈。我有一个TYPE类型的二叉树(TYPE是一个数据类型的*),可以添加和删除元素。但是由于某些原因,添加的某些值将覆盖以前的元素。这是我的代码,其中插入的示例没有覆盖元素,也没有覆盖元素。

我正在存储的数据:

struct data {
int number;
char *name;
};

typedef struct data data;

# ifndef TYPE
# define TYPE      data*
# define TYPE_SIZE sizeof(data*)
# endif

树形结构:

struct Node {
TYPE         val;
struct Node *left;
struct Node *rght;
};

struct BSTree {
struct Node *root;
int          cnt;
};

数据的比较器。

int compare(TYPE left, TYPE right) {
    int left_len; int right_len; int shortest_string;

    /* find longest string */
    left_len = strlen(left->name);
    right_len = strlen(right->name);
    if(right_len < left_len) { shortest_string = right_len; } else { shortest_string = left_len; }

    /* compare strings */
    if(strncmp(left->name, right->name, shortest_string) > 1) {
        return 1;
    }
    else if(strncmp(left->name, right->name, shortest_string) < 1) {
        return -1;
    }
    else {
        /* strings are equal */

        if(left->number > right->number) {
            return 1;
        }
        else if(left->number < right->number) {
            return -1;
        }
        else {
            return 0;
        }
    }
}

添加方法

struct Node* _addNode(struct Node* cur, TYPE val) {
    if(cur == NULL) {
        /* no root has been made */
        cur = _createNode(val);

        return cur;
    }
    else {
        int cmp;

        cmp = compare(cur->val, val);
        if(cmp == -1) {
            /* go left */

            if(cur->left == NULL) {
                printf("adding on left node val %d\n", cur->val->number);
                cur->left = _createNode(val);
            }
            else {
                return _addNode(cur->left, val);
            }
        }
        else if(cmp >= 0) {
            /* go right */

            if(cur->rght == NULL) {
                printf("adding on right node val %d\n", cur->val->number);
                cur->rght = _createNode(val);
            }
            else {
                return _addNode(cur->rght, val);
            }
        }

        return cur;
    }
}

void addBSTree(struct BSTree *tree, TYPE val)
{
tree->root = _addNode(tree->root, val);
tree->cnt++;
}

创建新节点的方法:

struct Node* _createNode(TYPE val) {
struct Node* new_node;
new_node = (struct Node*)malloc(sizeof(struct Node*));
new_node->val = val;
new_node->left = NULL;
new_node->rght = NULL;

return new_node;
}

打印树的功能:

void printTree(struct Node *cur) {
    if (cur == 0) {
        printf("\n");
    }
    else {
        printf("(");
        printTree(cur->left);
        printf(" %s, %d ", cur->val->name, cur->val->number);
        printTree(cur->rght);
        printf(")\n");
    }
}

以下是一些将覆盖以前元素的数据示例:

struct BSTree myTree;
struct data myData1, myData2, myData3;

myData1.number = 5;
myData1.name = "rooty";
myData2.number = 1;
myData2.name = "lefty";
myData3.number = 10;
myData3.name = "righty";

initBSTree(&myTree);
addBSTree(&myTree, &myData1);
addBSTree(&myTree, &myData2);
addBSTree(&myTree, &myData3);
    printTree(myTree.root);

将打印:

((
 righty, 10 
)
 lefty, 1 
)

最后,这里的一些测试数据将与之前的数据完全相同,但这次没有数据被覆盖:

struct BSTree myTree;
struct data myData1, myData2, myData3;

myData1.number = 5;
myData1.name = "i";
myData2.number = 5;
myData2.name = "h";
myData3.number = 5;
myData3.name = "j";

initBSTree(&myTree);
addBSTree(&myTree, &myData1);
addBSTree(&myTree, &myData2);
addBSTree(&myTree, &myData3);
printTree(myTree.root);

打印哪些:

((
 j, 5 
)
 i, 5 (
 h, 5 
)
)

有谁知道可能出现的问题?对不起,如果这篇文章有点长。

2 个答案:

答案 0 :(得分:1)

看起来你的_addNode程序有错误。看起来你没有在树中正确存储新的节点引用。

struct Node* _addNode(struct Node* cur, TYPE val) {
if(cur == NULL) {
    /* no root has been made */
    cur = _createNode(val);
    return cur;
}
else {
    int cmp;

    cmp = compare(cur->val, val);
    if(cmp == -1) {
        /* go left */
        cur->left = _addNode(cur->left, val);
    }
    else if(cmp >= 0) {
        /* go right */
        cur->left = _addNode(cur->right, val);
    }

    return cur;
}

_addnode函数有点令人困惑,因为你使用的返回值不一致。我相信这个版本应该避免丢失任何节点。

答案 1 :(得分:0)

我没有看到明显的缺陷。我建议重新处理树以保存int或比当前数据更简单的东西。如果树工作正常,那么至少你知道在哪里看,而不用担心通用树代码。

我怀疑_createNode(),你能添加那段代码吗?