在这种情况下,我如何声明一个新的结构?

时间:2015-09-18 05:33:03

标签: c binary-search-tree

这就是我现在所拥有的代码(只是一个简单的BST)

typedef struct bsn{
    int val;
    struct bsn *left, *right;
} bsn_t;

typedef struct bst{
    bsn_t *root;
    int size;
} bst_t;

我的问题是,对于我将要使用的功能,输入是这样的地址

void init( bst_t * tree )

我将如何使用它?这就是我现在所拥有的,但我不确定它是否正确

tree->size = 0;
tree->root = NULL;

还适用于

等其他功能
bool insert( bst_t *tree, int val )

我想声明要使用的临时节点。这有用吗?

bsn_t temp = (bsn_t *) malloc (sizeof (bsn_t));

我的最后一个问题是如何检查节点是否为空。我试过了

bsn_t visitor = (bsn_t*)malloc(sizeof(bsn_t));
visitor = *tree->root;

然后做

if (visitor != NULL)

但是当我编译它时说

  

'!=&#39 ;:结构

非法

请帮助..

3 个答案:

答案 0 :(得分:2)

在您的树中,节点与外部连接(即根)之间的连接都是指针。它们指向使用malloc在堆上分配的节点。

如果您定义一个局部变量,如:

bsn_t temp;

从堆栈中获取一个节点,该节点在从函数返回后将无效。在您的情况下,您永远不需要在堆栈上创建节点。您应该使用指向整个节点的指针,指向现有节点,指向严格分配的节点或不指向任何节点(NULL)。

所以:

bsn_t *temp = malloc (sizeof (bsn_t));

(我已将转换删除到(bsn_t *)。奇怪的是,在原始代码中,您在分配给结构时将返回值从malloc强制转换为指针类型。 )

至于你的第二个问题,你的代码是:

bsn_t visitor = (bsn_t*)malloc(sizeof(bsn_t));
visitor = *tree->root;

在几个地方都错了。首先,如上所述,visitor应该是指向节点的指针,而不是节点结构。

然后访客应该从根树下游。通过这样做,它不会创建任何新节点,因此根本不需要malloc。请记住,malloc为堆提供了新内存,实际上是创建节点。 visitor只指向现有对象。一个对象可以有更多指针指向它们。

即使malloc是正确的做法,你也不应该malloc然后覆盖保存ne存储器(仅限目前)句柄的指针。

您还遇到*错误。 visitor是一个指针ans tree->root也是一个指针,所以不需要取消引用。你所做的是将root的内容复制到你的本地结构。

你想要做的是这样:

bsn_t *visitor = tree->root;

while (visitor != NULL) {
    // Do stuff

    visitor = visitor->right;    // or left, whatever
}

在声明和使用中使用星号可能会造成混淆。在声明中,您使用start来使事物成为指针:

bsn_t node;      // uninitialised node struct on the stack
bsn_t *pnode;    // uninitialised pointer to node

之后,当您使用指针变量时,未加修饰的名称引用指针。星号表示您取消引用它以获取指针指向的内容。当您使用结构时,您通常不会看到很多星星,因为首选->语法,但node->left(*node).left基本相同。

答案 1 :(得分:0)

您无法将内存地址(malloc调用的返回值)分配给结构类型变量。您需要将这些分配给指针类型变量。

bsn_t *temp = (bsn_t *) malloc (sizeof (bsn_t));

bsn_t *visitor = (bsn_t*)malloc(sizeof(bsn_t));

然后你就不会有编译时错误。

答案 2 :(得分:0)

我该如何使用它?这就是我现在所拥有的,但我不确定它是否正确 tree-> size = 0; tree-> root = NULL;

是的,这是使用它的正确方法。如果你有一个指针,你可以用( - >)运算符访问struct元素,否则,使用。 (点)运算符。

bsn_t temp =(bsn_t *)malloc(sizeof(bsn_t));

是的,这也是正确的方法,但你在左手边的temp之前缺少'*',这表明这是一个指针类型变量。请记住,它会在堆中分配对象,因此当您不再需要它时,必须明确释放该内存。另外,请注意,将新分配的内存转换为(bsn_t *)是可选的,如果不这样做,编译器将隐式为您执行此操作,具体取决于您的l值类型。

bsn_t visitor =(bsn_t *)malloc(sizeof(bsn_t));

同样,左侧应该是 bsn_t * visitor

visitor = * tree-> root; 接下来它应该是 * visitor = * tree-> root; 此外,尝试通过编写*(temp-> root)而不是* temp-> root来使代码更具可读性。

if(visitor!= NULL)现在你应该可以使用它了,因为访问者现在是一个指针。