[英]Printing B+ tree in C
我已经在C
实现了B+
树,并希望以树形式打印其键。 我遵循以下算法进行打印,但遇到了一些分割错误。
从根开始,首先对其进行排队。 然后出队直到队列变为零。
由于每个节点都包含键及其值(指向下一级节点的指针),因此这些值中的每一个在到达特定节点时也会排队。
以下是对叶子进行排队,出队和打印的代码。 请让我知道此partcularcode有什么问题。
typedef struct QUEUE{
BPLUS bplusNode;
struct QUEUE * next;
}*ENQUEUE;
以下代码是对树的节点进行排队。(我将实现广度优先搜索)
void bplus_Enqueue(BPLUS bplusNew){
ENQUEUE bplusTemp;
if (queue == NULL){
queue = (ENQUEUE)malloc(sizeof(ENQUEUE));
queue->bplusNode= bplusNew;
queue->next = NULL;
}
else {
bplusTemp = (ENQUEUE)malloc(sizeof(ENQUEUE));
bplusTemp->bplusNode = bplusNew;
bplusTemp->next = NULL;
while(queue->next != NULL) {
queue = queue->next;
}
queue->next = bplusTemp;
free(bplusTemp);
}
}
以下代码用于出队
BPLUS bplus_Dequeue( void ){
BPLUS bplusTemp = queue->bplusNode;
queue = queue->next;
return bplusTemp;
}
以下代码用于打印树。
void bplus_PrintBplus(BPLUS root){
int i;
BPLUS tempBplus;
queue = NULL;
bplus_Enqueue(root);
if(queue == NULL){
printf("Sala kaam garena\n");
}
while(queue != NULL){
tempBplus = bplus_Dequeue();
for(i=0;i<tempBplus->numKeys;i++){
printf("%d -----> %d\n",i,tempBplus->keys[i]);
}
if(tempBplus->next != NULL){
for(i=0;i<=tempBplus->numKeys;i++)
bplus_Enqueue(tempBplus->pointers[i]);
}
}
}
此代码打印root
的键值和root
第一个连续节点,然后出现分段错误。 您能帮我弄清楚这段代码有什么问题吗?
我没有检查完整的代码,但是这些部分确实很奇怪:
bplusTemp->bplusNode = bplusNode;
这里的bplusNode是什么? 还没有看到它的声明。
queue->next = bplusTemp;
free(bplusTemp);
这只是简单的坚果:)
级别顺序遍历是通过两个队列完成的,一个队列用于访问当前级别的元素,另一个队列用于为下一个级别建立队列。 我已经为二进制搜索树成功实现了这一点。 您可以对B +树使用相同的逻辑。
void BinarySearchTree::printLevelBased()
{
Queue<Node *> *nodeQueue1 = new Queue<Node *>();
Queue<Node *> *nodeQueue2 = new Queue<Node *>();;
Node *currentNode;
int numOfLevels = 0;
nodeQueue1->put(mRoot);
while(false == nodeQueue1->isEmpty())
{
numOfLevels++;
Queue<Node *> *temp = nodeQueue1;
nodeQueue1 = nodeQueue2;
nodeQueue2 = temp;
while(false == nodeQueue2->isEmpty())
{
currentNode = nodeQueue2->get(); // Dequeue
PRINT_NODE_DATA(currentNode);
if(currentNode->hasLeft())
{
nodeQueue1->put(currentNode->mLeft); // Enqueue
}
if(currentNode->hasRight())
{
nodeQueue1->put(currentNode->mRight);
}
}
cout << endl;
}
return;
}
词shash
这行代码在bplus_Enqueue
函数中看起来很奇怪:
queue->next = bplusTemp;
free(bplusTemp);
基本上,您是在队列使用的链表中设置下一个节点,但是在将next
指针分配给链表的上一个末尾之后将其释放。 这意味着您的倒数第二个节点指向的是释放的内存,而不是有效的链表节点,这将在访问它时导致分段错误。 第一行之后,由bplusTemp
节点指向的内存现在已由列表“拥有” ...您不能在该指针上调用free
,否则不能指向该内存的所有其他指针(在这种情况下为queue->next
)也指向已释放的内存,并且在尝试访问该内存时将出现段错误。
这对于为什么您能够打印前两个节点值(根及其子节点之一)并获得段错误也很有意义。 基本上,当队列为空时,您永远不会调用这些行,而是要添加第一个节点。 因此,当您添加root
,您就可以了……您不会对其free
打电话。 然后,将其出队,然后再将其清空。 因此,将root
的下一个孩子添加到队列中,这也很好,因为因为队列为空,所以您不必在bplusNew
上调用free
。 但是现在,当您添加根的任何其他子级并且队列不为空时,您最终在bplusNew
上调用free
,导致队列仅包含单个值。 换句话说, queue->next
指向的第一个节点(即链表中的第二个节点)实际上不再可用了……您在该内存上称为free
。
其次,在您的bplus_Dequeue
函数中,存在内存泄漏...特别是在这里:
BPLUS bplusTemp = queue->bplusNode;
queue = queue->next;
您要重新分配链表的最前面,而不会释放作为链表原头的节点。 现在,您不再有指向该节点的指针,并且它被视为内存泄漏。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.