打印二叉树某一层的节点

按层非递归遍历二叉树是一道常见的题目,编程之美上有一个打印出二叉树某一层的节点的问题,稍稍有意思。

在编程之美上,提到了两种解法:

(1)一种是递归解法

void TransLevel(Node* root,int level)

{

    if(root == NULL)

        return ;

    else

    {

        if(level == 1)

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

        else

        {

            TransLevel(root->left,level-1);

            TransLevel(root->right,level-1);

        }

    }

}

  (2)另一种则是利用队列的非递归解法

如果只是简单的按层遍历的话,可以用一个队列,先将上层节点入队,节点出队的时候将其孩子节点入队,这样就可以达到按层入队出队的效果。

要打印出某一层,可以在出队的时候一层一层地出,同时计算出队的次数,就可以判断出当前是哪一层,下面是我的代码:

void TransLevel2(Node* root,int level)

{

    if(root == NULL)

        return ;

    else

    {

        int count_levels,count_nodes,level_nodes;

        Node* tmp;

        Queue<Node*> queue;

        queue.EnQueue(root);

        

        count_levels=1;



        while(!queue.IsEmpty())

        {

            //如果已经是要打印的层

            if(count_levels == level)

                break;



            count_nodes = 0;

            //计算上一层的节点数

            level_nodes = queue.Size();

            

            //每一次将一个节点出队,直至上一层所有节点出队

            //同时将下一层的节点入队

            while(count_nodes < level_nodes)

            {

               tmp = queue.DeQueue();



               if(tmp->left != NULL)

                    queue.EnQueue(tmp->left);



               if(tmp->right != NULL)

                    queue.EnQueue(tmp->right);



               count_nodes++;

            }



            count_levels++;

        }

        //队列中剩下的元素即为要打印的节点

        PrintQueue(queue);

    }

}

里面用到的队列是自己写的,也当作一个小练习。

完整测试代码:

queue.h
#ifndef __QUEUE_H__

#define __QUEUE_H__



#include <memory.h>



#define MAX_SIZE 100



template <typename T>

class Queue

{

    public:

        Queue();

        bool EnQueue(const T element);

        T DeQueue();

        bool IsEmpty() const;

        bool IsFull() const;

        int Size() const;



    private:

        T queue[MAX_SIZE];

        int front;

        int rear;

};



template<typename T>

Queue<T>::Queue()

:front(0),rear(0)

{

    memset(queue,0,sizeof(queue));    

}



template<typename T>

bool Queue<T>::EnQueue(const T element)

{

    if(IsFull())

        return false;

    else

    {

        rear = (rear+1)%MAX_SIZE;

        queue[rear] = element;

        return true;

    }

}



template<typename T>

T Queue<T>::DeQueue()

{

    if(IsEmpty())

        return 0;

    else

    {

        front = (front+1)%MAX_SIZE;

        return queue[front];

    }

}



template<typename T>

bool Queue<T>::IsEmpty() const

{

    return front == rear;

}



template<typename T>

bool Queue<T>::IsFull() const

{

    return (rear+1) % MAX_SIZE == front;

}



template<typename T>

int Queue<T>::Size() const

{

    return rear-front;

}



#endif /* __QUEUE_H__ */
btree.h
#ifndef __BTREE_H__

#define __BTREE_H__



struct Node

{

    struct Node* left;

    struct Node* right;

    int data;

};



void BuildTree(int array[],int n,struct Node** root,int i);



void DestroyTree(struct Node* root);



void PrintTree(Node* root);



int GetDepth(Node* root);



void TransLevel(Node* root,int level);



void TransLevel2(Node* root,int level);



#endif /* __BTREE_H__ */
btree.cc
#include "btree.h"

#include <memory.h>

#include <stdlib.h>

#include <stdio.h>

#include "queue.h"



void BuildTree(int array[],int n,Node** root,int i)

{

    if(i<n)

    {

        *root = (Node*)malloc(sizeof(Node));

        (*root)->data = array[i];



        BuildTree(array,n,&(*root)->left,i*2+1);

        BuildTree(array,n,&(*root)->right,(i+1)*2);

    }

}



void DestroyTree(Node* root)

{

    if(root!=NULL)

    {

        DestroyTree(root->left);

        DestroyTree(root->right);



        free(root);

    }

}



void PrintTree(Node* root)

{

    if(root!=NULL)

    {

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



        PrintTree(root->left);

        PrintTree(root->right);

    }

}



int GetDepth(Node* root)

{

    if(root == NULL)

        return 0;

    else

    {

        int left_depth=GetDepth(root->left);

        int right_depth=GetDepth(root->right);



        return left_depth>right_depth ? left_depth+1 : right_depth+1;

    }

}



void TransLevel(Node* root,int level)

{

    if(root == NULL)

        return ;

    else

    {

        if(level == 1)

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

        else

        {

            TransLevel(root->left,level-1);

            TransLevel(root->right,level-1);

        }

    }

}



static void PrintQueue(Queue<Node*>& queue)

{

    Node* node = NULL;

    while(!queue.IsEmpty())

    {

       node = queue.DeQueue();

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

    }

}



void TransLevel2(Node* root,int level)

{

    if(root == NULL)

        return ;

    else

    {

        int count_levels,count_nodes,level_nodes;

        Node* tmp;

        Queue<Node*> queue;

        queue.EnQueue(root);

        

        count_levels=1;



        while(!queue.IsEmpty())

        {

            if(count_levels == level)

                break;



            count_nodes = 0;

            level_nodes = queue.Size();

            

            while(count_nodes < level_nodes)

            {

               tmp = queue.DeQueue();



               if(tmp->left != NULL)

                    queue.EnQueue(tmp->left);



               if(tmp->right != NULL)

                    queue.EnQueue(tmp->right);



               count_nodes++;

            }



            count_levels++;

        }

        PrintQueue(queue);

    }

}
main.cc
#include <stdio.h>

#include "btree.h"



int main()

{

    int array[]={1,2,3,4,5,6,7,8,9,10};

    Node* root=NULL;



    BuildTree(array,10,&root,0);

    

    int depth = GetDepth(root);



    /* 使用递归方法打印二叉树的某一层 */

    for(int i=1;i<=depth;i++)

        TransLevel(root,i);

    printf("\n");



    /* 使用非递归方法打印二叉树的某一层 */

    for(int i=1;i<=depth;i++)

        TransLevel2(root,i);

    printf("\n");



    DestroyTree(root);



    return 0;

}

 

你可能感兴趣的:(二叉树)