我目前正在处理具有这种结构的通用树:
ALTER TABLE table_name RENAME old_col_name TO new_col_name;
虽然分配不同节点的功能是(不要过多地关注键的值,基本上分配子节点。如果没有任何新子进入左子节点,否则它会进入列表的末尾“node-> leftchild-> rightbrothers”):
typedef struct NODE {
//node's keys
unsigned short *transboard;
int depth;
unsigned int i;
unsigned int j;
int player;
int value;
struct NODE *leftchild; //points to the first child from the left
struct NODE *rightbrothers; //linked list of brothers from the current node
}NODE;
static NODE *GameTree = NULL;
我需要提出一个函数,可能是递归的,解除整个树的释放,到目前为止我已经想出了这个:
static int AllocateChildren(NODE **T, int depth, unsigned int i, unsigned int j, int player, unsigned short *transboard) {
NODE *tmp = NULL;
if ((*T)->leftchild == NULL) {
if( (tmp = (NODE*)malloc(sizeof(NODE)) )== NULL) return 0;
else {
tmp->i = i;
tmp->j = j;
tmp->depth = depth;
(player == MAX ) ? (tmp->value = 2 ): (tmp->value = -2);
tmp->player = player;
tmp->transboard = transboard;
tmp->leftchild = NULL;
tmp->rightbrothers = NULL;
(*T)->leftchild = tmp;
}
}
else {
NODE *scorri = (*T)->leftchild;
while (scorri->rightbrothers != NULL)
scorri = scorri->rightbrothers;
if( ( tmp = (NODE*)malloc(sizeof(NODE)) )== NULL) return 0;
else {
tmp->i = i;
tmp->j = j;
tmp->depth = depth;
(player == MAX) ? (tmp->value = 2) : (tmp->value = -2);
tmp->player = player;
tmp->transboard = transboard;
tmp->leftchild = NULL;
tmp->rightbrothers = NULL;
}
scorri->rightbrothers = tmp;
}
return 1;
}
但它似乎没有用,它甚至没有释放单个内存节点。 我对错误或如何实施的想法? 附:我从老师的伪代码中得到了递归函数的想法。但是我不确定我是否已经使用我的树种在C中正确翻译了它。 伪代码:
void DeleteTree(NODE **T) {
if((*T) != NULL) {
NODE *tmp;
for(tmp = (*T)->children; tmp->brother != NULL; tmp = tmp->brother) {
DeleteTree(&tmp);
}
free(*T);
}
}
答案 0 :(得分:0)
如果我要分配大量的树节点(我将同时消失),我喜欢做的一件事就是在'批次'中分配它们。然后我malloc
作为一个节点数组,在保存指向数组的指针后(在下面的函数中)从特殊的nodealloc
函数中删除它们。要删除树,我只是确保我没有保留任何引用,然后调用自由例程(也如下所示)。
如果您对初始malloc
幸运(或非常聪明)或者可以信任realloc
在缩小块时不移动块,这也可以减少您分配的RAM量。
struct freecell { struct freecell * next; void * memp; } * saved_pointers = 0;
static void
save_ptr_for_free(void * memp)
{
struct freecell * n = malloc(sizeof*n);
if (!n) {perror("malloc"); return; }
n->next = saved_pointers;
n->memp = memp;
saved_pointers = n;
}
static void
free_saved_memory(void)
{
while(saved_pointers) {
struct freecell * n = saved_pointers;
saved_pointers = saved_pointers->next;
free(n->memp);
free(n);
}
}
答案 1 :(得分:0)
我刚刚在代码中意识到我的大错,因为没有人找到答案,我只会自己回答。
错误在于这段代码:
for(tmp = (*T)->children; tmp->brother != NULL; tmp = tmp->brother) {
DeleteTree(&tmp);
}
首先Ami Tavory对于for条件是正确的,我需要继续只要tmp!= NULL 基本上它不会起作用,因为在DeleteTree(& tmp)之后,我无法再访问tmp中的内存因为它显然被删除,所以在第一个循环结束后我不能do tmp = tmp-> rightbrother移动下一个要删除的节点因为tmp-> rightbrother不再存在,因为我刚删除它。 为了解决这个问题,我只需要在其他地方保存tmp->兄弟:
void DeleteTree(NODE **T) {
if((*T) != NULL) {
NODE *tmp, *deletenode, *nextbrother;
for(tmp = (*T)->children; tmp != NULL; tmp = nextbrother) {
nextbrother = tmp->rightbrother;
DeleteTree(&tmp);
}
canc = (*T);
free(*T);
(*T) = NULL;
}
}
答案 2 :(得分:0)
为了完整起见,我想添加我的DeleteTree版本
void DeleteTree(NODE *T) {
if(T != NULL) {
DeleteTree(T->rightbrothers);
DeleteTree(T->leftchild);
free(T);
}
}
我认为它不那么模糊,也更容易阅读。基本上它解决了DeleteTree中的问题,但通过消除循环。
由于我们递归地释放节点,我们也可以递归地执行整个过程。