简体   繁体   中英

Printing B+ tree in C

I have implemented B+ tree in C and wants to print its keys in the tree form. I followed the following algorithms for printing it but getting some segmentation fault.

  1. Starting from root, first of all queuing it. Then dequeing until the queue becomes nil.

  2. As each node contains both keys and their values(pointers to next level nodes), each of those values are also queued while reaching the particular node.

Following is the code for queuing,dequeuing and printing the leaf. Please let me know what is wrong with this partcularcode.

           typedef struct QUEUE{
            BPLUS bplusNode;
            struct QUEUE * next;
                    }*ENQUEUE;

Following code is to queue the nodes of tree.(I am going to implement Breadth first search)

      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);
                   }
             }

Following code is for dequeuing

          BPLUS bplus_Dequeue( void ){
          BPLUS bplusTemp = queue->bplusNode;
          queue = queue->next;
          return bplusTemp;
           }

Following code is for printing the tree.

   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]);
            }
        }
    }

This code prints the key value of root and first successive node of root and then gets segmentation fault. Could you please help me to figure out what is wrong with this code?

I haven't checked the full code, but these parts are really weird:

bplusTemp->bplusNode = bplusNode;

What's bplusNode here? Haven't seen its declaration.

queue->next = bplusTemp;
free(bplusTemp);

this is just plain nuts :)

Level order traversal is done through two queues, one for accessing elements in the current level and the other one for building the queue for next level. I have successfully implemented this for Binary Search Tree. You can use the same logic for B+ trees.

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

This line of code looks odd in your bplus_Enqueue function:

queue->next = bplusTemp;
free(bplusTemp);

basically you are setting the next node in the linked-list you're using for your queue, but then freeing it after assigning the next pointer to the previous end of the linked list. That is going to mean that your next-to-last node is pointing to freed memory rather than a valid linked-list node, which will cause a segmentation fault when it's accessed. The memory being pointed to by bplusTemp node, after the first line, is now "owned" by the list ... you can't call free on that pointer, or else every other pointer that points to that memory (in this case queue->next ) is also pointing to freed memory and will segfault when it tries to access that memory.

This would also make sense on why you are able to print the first two node values (root, and one of its children), and then get a segfault. Basically you never call those lines when the queue is empty, and you're adding the first node. So when you add root , you're okay ... you don't call free on it. You then dequeue it, and when you do that, the queue is empty again. So the next child of root is added to the queue, and that again is fine, since because the queue was empty, you don not call free on bplusNew . But now when you add any other children of the root, and the queue is not empty, you end up calling free on bplusNew , causing you queue to only contain a single value value. In other words the first node being pointed to by queue->next (ie, the second node in the linked list), is actually not accessible anymore ... you've called free on that memory.

Secondly, in your bplus_Dequeue function you have a memory leak ... specifically here:

BPLUS bplusTemp = queue->bplusNode;
queue = queue->next;

You're re-assigning the front of the linked-list without freeing the node that was the original head of the list. Now you don't have a pointer to that node anymore, and it's considered leaked memory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM