打印二叉樹某一層的節點


按層非遞歸遍歷二叉樹是一道常見的題目,編程之美上有一個打印出二叉樹某一層的節點的問題,稍稍有意思。

在編程之美上,提到了兩種解法:

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM