简体   繁体   English

C 中使用队列的级别顺序树遍历

[英]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.它应该打印树中的所有节点,但由于某种原因我无法弄清楚,output 只是根数据。 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否则,例如 function dequeue会在如下语句中产生大量 memory 泄漏

q->head->node = NULL;

or returned and created one more a node of the type qNode is not freed in the function levelOrder .或返回并再创建一个qNode类型的节点未在 function levelOrder中释放。

Also you are not setting the data member end to NULL after this statement此外,您没有在此语句之后将数据成员end设置为NULL

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程序 output 是

2 7 5 9 6 128 223 357 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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