1

我使用 c 制作了一个树形结构,并用它来存储国际象棋游戏的一些动作。我的结构是

struct node{
        NSString *comment;
        NSString *move;
        struct node *variationLink;
        struct node *nextLink;
        struct node *goBack;
    };

我使用 malloc 创建节点。当游戏被更改或卸载时,我想释放树有没有办法在 dalloc 中做到这一点,或者我必须创建一个函数来到达每个节点并释放它?

4

2 回答 2

2

为节点实现析构函数。

free()如果节点内的所有节点都只是链接,则用于主节点。

于 2012-06-29T07:45:23.110 回答
2

您需要创建一个递归释放结构的函数,例如:

void free_nodes(struct node *n)
{
    if (n != NULL)
    {
        free_nodes(n->nextLink);
        free_nodes(n->variationLink);
        [n->comment release];
        [n->move release];
        free(n);
    }
}

然后从您的dealloc方法中调用它:

- (void)dealloc
{
    free_nodes(_root_node);
    [super dealloc];
}

其他的建议:

  • 您需要一个指向变体主线的链接,这相当于goBack指针,但用于变体。这将允许您横向回到任何节点的主线,因为目前没有办法完全横向执行您的树。
  • 我会重命名为goBack,prevnextLink,next但这真的取决于你。variationLinkvariation
  • 您需要使用内部格式存储移动,而不是NSString. 字符串应该只在显示期间生成(在视图的 draw 方法中)。这允许您实际使用移动数据,而不必再次解析字符串(非常昂贵),并且仅在显示期间进行字符串转换允许您根据用户偏好更改移动字符串的生成方式(短代数符号,长代数符号,坐标符号,使用块字符字体而不是字母等)。

来自 OP 的问题后编辑:为了让您的树存储多个变体,您需要创建变体的双向链接列表。因此该节点将成为两个双向链表的一部分。用 C++ 编写会有所帮助,但如果您使用的是 C,我会用 C 来展示它:

typedef struct node
{
    Move move;    // Holds the move (this can be done using a 32-bit unsigned integer).
    struct node *prev;
    struct node *next;
    struct node *variation;
    struct node *mainline;
    NSString *comment;
} Node;

这里的mainline链接指向之前的变化,NULL如果这是主线移动的话。

移动 1.e4 e5 (1...Nf6 a4) (1...Nc6 b4) 2.Nc3 将使用这样的树进行保存(如果链接未显示在节点上,则它们是NULL):

在此处输入图像描述

我在我正在开发的国际象棋程序中使用这种方法,它运行得很好。重新迭代;我将数据(此节点)与演示文稿(包含 UI 中显示的移动文本的字符串)分开。生成的移动字符串应该以完全不同的方式保存;也许是 Core Text,但我使用的是自定义方法。

于 2012-06-29T08:52:11.370 回答