简体   繁体   中英

Level Order Tree Traversal in C using queues

I'm trying to implement an algorithm of level order traversal in a binary tree using a queue(the queue is implemented using linked lists). It should print all the nodes in the tree but, for some reason i can't figure out, the output is just the root data. If you could help me I would appreciate it very much: Here's my code:`

#include <stdio.h>
#include <stdlib.h>

typedef struct BSTNode{
    int data;
    struct BSTNode* left;
    struct BSTNode* right;
} bstNode;

/* Queue */
typedef struct queueNode{
    bstNode* node;
    struct queueNode* next;
} qNode;

typedef struct Queue
{
    qNode* head;
    qNode* end;
} queue;



bstNode* getNewNode(int data){
    bstNode* newNode = (bstNode*)malloc(sizeof(bstNode));
    if(!newNode)
        return NULL;
    newNode->data = data;
    newNode->left = NULL;
    newNode->right = NULL;

    return newNode;
}

void insertBSTNode(bstNode** root, int data){
    if(*root == NULL){ // empty tree
        *root = getNewNode(data);}
    else if((*root)->data >= data)
        insertBSTNode(&((*root)->left), data);
    else insertBSTNode(&((*root)->right), data);
}


queue* initQ(){
    queue* q = (queue*)malloc(sizeof(queue));
    if(!q) return NULL;
    q->head = NULL;
    q->end = NULL;

    return q;
}

qNode* allocNewQNode(bstNode* root)
{
    qNode* newNode = (qNode*)malloc(sizeof(qNode));
    if (!newNode) return NULL;
    newNode->node = (bstNode*)malloc(sizeof(bstNode));
    if(!newNode->node){ 
        free(newNode);
        return NULL;
    }
    //memcpy(newNode->node, root, sizeof(bstNode));
    newNode->node->data = root->data;
    newNode->node->left = root->left;
    newNode->node->right = root->right;
    newNode->next = NULL;

    return newNode;
}

void enqueue(queue* q, bstNode* root)
{
    qNode* tmp = allocNewQNode(root);
    if(q->head == NULL && q->end == NULL){

        q->head = tmp;
        q->end = tmp;
        return;
    }
    else{
        q->end->next = tmp;
        q->end = tmp;
        return;
    }

}

qNode* dequeue(queue* q)
{   
    if(q->head == NULL) return NULL;
    qNode* tmp = allocNewQNode(q->head->node);
    qNode* aux = NULL;
    q->head->node = NULL;

    aux = q->head;
    q->head = q->head->next;
    free(aux);

    return tmp;

}

void levelOrder(bstNode* root)
{
    if(root == NULL) return;
    else
    {
        queue* q = initQ();
        enqueue(q, root);
        while(q->head != NULL){
            qNode* tmp = dequeue(q);
            printf("%d ", tmp->node->data);
            if (tmp->node->right != NULL){
                enqueue(q, tmp->node->right);
            }
            if(tmp->node->left != NULL){
                enqueue(q, tmp->node->left);
            }
        }
    }

}

int main(){

    bstNode* root = NULL;
        insertBSTNode(&root, 2);
        insertBSTNode(&root, 7);
        insertBSTNode(&root, 5);
        insertBSTNode(&root, 6);
        insertBSTNode(&root, 9);
        insertBSTNode(&root, 128);
        insertBSTNode(&root, 223);
        insertBSTNode(&root, 357);


    levelOrder(root);
    return 0;
}

`

For the inserted data you should have the following binary search tree

2
 \
  7
 / \
5   9
\    \
 6    128
       \
       223
        \
        357 

and the level order traversal of the tree should;look like

2 7 5 9 6 128 223 357 

Building the queue you shall not dynamically allocate copies of nodes of the binary search tree.

Otherwise for example the function dequeue produces numerous memory leaks in statements like

q->head->node = NULL;

or returned and created one more a node of the type qNode is not freed in the function levelOrder .

Also you are not setting the data member end to NULL after this statement

q->head = q->head->next; 

when the queue contained only one node

And there is no need to define the queue itself dynamically.

Here is a demonstrative program that shows how the functions can be defined using your approach.

#include <stdio.h>
#include <stdlib.h>

typedef struct BSTNode
{
    int data;
    struct BSTNode *left;
    struct BSTNode *right;
} bstNode;

/* Queue */
typedef struct queueNode
{
    bstNode* node;
    struct queueNode *next;
} qNode;

typedef struct Queue
{
    qNode *head;
    qNode *end;
} queue;

bstNode * getNewNode( int data )
{
    bstNode* newNode = malloc( sizeof( bstNode ) );

    if ( newNode != NULL )
    {
        newNode->data  = data;
        newNode->left  = NULL;
        newNode->right = NULL;
    }

    return newNode;
}

int insertBSTNode( bstNode **root, int data )
{
    return *root == NULL 
           ? ( *root = getNewNode( data ) ) != NULL
           : ( data < ( *root )->data 
               ? insertBSTNode( &( *root )->left, data )
               : insertBSTNode( &( *root )->right, data ) );
}

void initQ( queue *q )
{
    q->head = NULL;
    q->end  = NULL;
}

qNode * allocNewQNode( bstNode *node )
{
    qNode *newNode = malloc( sizeof( qNode ) );

    if ( newNode != NULL )
    {
        newNode->node = node;
        newNode->next = NULL;
    }

    return newNode;
}

void enqueue( queue *q, bstNode *node )
{
    qNode *tmp = allocNewQNode( node );

    if ( q->head == NULL )
    {
        q->head = q->end = tmp;
    }
    else
    {
        q->end = q->end->next = tmp;
    }
}

bstNode * dequeue( queue *q )
{
    bstNode *node = q->head == NULL ? NULL : q->head->node;

    if ( q->head != NULL )
    {
        qNode *tmp = q->head;
        q->head = q->head->next;

        free( tmp );

        if ( q->head == NULL ) q->end = NULL;
    }

    return node;    
}

void levelOrder( bstNode *root )
{
    if ( root != NULL )
    {
        queue q;
        initQ( &q );

        enqueue( &q, root );

        while ( q.head != NULL )
        {
            bstNode *tmp = dequeue( &q );

            printf( "%d ", tmp->data );

            if ( tmp->left != NULL )
            {
                enqueue( &q, tmp->left );
            }

            if ( tmp->right != NULL )
            {
                enqueue( &q, tmp->right );
            }
        }
    }
}

int main(void) 
{
    bstNode *root = NULL;

    insertBSTNode( &root, 2 );
    insertBSTNode( &root, 7 );
    insertBSTNode( &root, 5 );
    insertBSTNode( &root, 6 );
    insertBSTNode( &root, 9 );
    insertBSTNode( &root, 128 );
    insertBSTNode( &root, 223 );
    insertBSTNode( &root, 357 );

    levelOrder( root );

    putchar( '\n' );

    return 0;
}

The program output is

2 7 5 9 6 128 223 357 

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