node *tree_get_last_child(node *n){ while(n!=NULL && n->last_child!=NULL){ n=n->last_child; } return(n); }
时间: 2023-12-19 12:07:17 浏览: 43
这段代码是一个函数,实现的功能是获取一棵树的最后一个子节点。函数的参数是一个指向树节点的指针。函数的返回值是指向最后一个子节点的指针。
函数的实现思路是从当前节点开始,一直向下遍历,直到遍历到最后一个子节点为止。在遍历过程中,如果当前节点没有子节点,则函数返回当前节点。如果当前节点有子节点,则继续向下遍历。
需要注意的是,函数的参数不能为 NULL,否则会导致程序崩溃。如果要获取整棵树的最后一个子节点,可以将根节点作为参数传入函数中。
相关问题
void tree_get_leafs(tree *t,int id){//打印所有叶子节点的ID node *n=tree_find_node(t,id); while(n!=NULL && n->last_child!=NULL){ n=n->last_child; } while(n!=NULL){ if(n->first_child==NULL){ printf("\n\t%d",n->d->id); } if(n->d->id==id){ break; }else{ n=tree_get_prev_node(n);//获得前面的节点 } } }用遍历的方式改写以上代码
以下是用遍历方式改写的代码:
```
void tree_get_leafs(tree *t, int id) {
node *n = tree_find_node(t, id);
if (n == NULL) return;
if (n->first_child == NULL) {
printf("\n\t%d", n->d->id);
} else {
node *stack[MAX_STACK_SIZE]; // 定义一个栈,用于存储遍历时的节点
int top = -1; // 栈顶指针初始化为-1
stack[++top] = n; // 将根节点入栈
while (top != -1) { // 当栈不为空时
node *cur = stack[top--];
if (cur->first_child == NULL) { // 如果当前节点是叶子节点
printf("\n\t%d", cur->d->id);
} else { // 如果当前节点有子节点
node *child = cur->last_child;
while (child != NULL) { // 将子节点入栈
stack[++top] = child;
child = child->prev_sibling;
}
}
}
}
}
```
该代码使用了一个栈来遍历树的节点,每次从栈中弹出一个节点,并将其子节点入栈,直到找到叶子节点为止。这样可以避免使用递归函数,提高代码效率。
Node* Delete(Key& key_data, uint32_t key_hash, EditType type = DELETE_TYPE, HashValue<Value>* value_mem = NULL, Value* value = NULL) { Bucket* bucket = hash_bucket_ + key_hash; int conflict_count = 0; if (bucket->head_node_ == NULL) { SetConflictCount(DELETE_TYPE, conflict_count); return NULL; } Node* pre_node = NULL; Node* cur_head_node = bucket->head_node_; Node* free_node = cur_head_node; while(free_node) { conflict_count++; if (CmpKey(free_node->key_, key_data)) { DoubleLinkRemoveAt(&double_link_, &free_node->doublelink_node_); value_mem->ReleaseOneValue(free_node->value_->node_ptr_); free_node->value_ = NULL; free_node->key_.Reset(); if (free_node == cur_head_node) {//头结点被释放 if (free_node->next_node_ == NULL) {//只有一个节点 bucket->head_node_ = NULL; } else { bucket->head_node_ = free_node->next_node_; } } else {//非头结点被释放 pre_node->next_node_ = free_node->next_node_; } ReleaseNode(free_node); SetConflictCount(DELETE_TYPE, conflict_count); return (Node*)1; //特殊返回 ! } pre_node = free_node; free_node = free_node->next_node_; } SetConflictCount(DELETE_TYPE, conflict_count); return NULL; }什么意思
这段代码是哈希表中删除一个节点的函数实现。传入参数包括key_data(要删除节点的键值)、key_hash(键值的哈希值)、type(编辑类型,默认为删除类型)、value_mem(哈希表中value的内存分配器)、value(要删除节点的值)。
函数首先找到哈希表中对应的bucket,然后遍历bucket中的所有节点,查找要删除的节点。如果找到了,就从双向链表中删除该节点,并释放其占用的内存空间。如果被删除的节点是头结点,需要特殊处理。最后返回一个指针,如果是特殊返回值1,表示删除成功;如果是NULL,表示未找到要删除的节点。
阅读全文