层次遍历二叉树(编程之美3.10)

问题(假定根节点位于第0层)

1. 层次遍历二叉树(每层换行分开)

2. 层次遍历二叉树指定的某层

例如

上图中

1.

1
2 3
4 5 6
7 8

2.

第三层
7 8

可以看出得出第二问的解,第一问迎刃而解了,所以从问题二下手

分析与解

1. 层次遍历二叉树指定的某层

可以得出这样的一个结论:遍历二叉树的第k层,相当于遍历二叉树根节点的左右子树的第k-1层。这样一直遍历下去,直到k=0时,输出节点即可。

参考代码

int PrintNodeAtLevel(BiTree root, int level)
{
    if(!root || level < 0)
        return 0;
    else if(level == 0)
    {
        cout << root->data << endl;
        return 1;
    }
    else
        return PrintNodeAtLevel(root->left, level - 1) + PrintNodeAtLevel(root->right, level - 1);
}

完整执行代码

#include<iostream>
using namespace std;
typedef struct BiTNode
{
    int data;
    BiTNode *left;
    BiTNode *right;
}BiTNode, *BiTree;

void createTree(BiTree &root)
{
    BiTree left1 = new(BiTNode);
    BiTree right1 = new(BiTNode);
    
    left1->data = 1;
    left1->left = NULL;
    left1->right = NULL;
    right1->data = 2;
    right1->left = NULL;
    right1->right = NULL;

    root->left = left1;
    root->right = right1;


    BiTree left2 = new(BiTNode);
    left2->data = 3;
    left2->left = NULL;
    left2->right = NULL;
    BiTree right2 = new(BiTNode);
    right2->data = 4;
    right2->left = NULL;
    right2->right = NULL;
    left1->left = left2;
    left1->right = right2;

    BiTree left3 = new(BiTNode);
    left3->data = 5;
    left3->left = NULL;
    left3->right = NULL;
    BiTree right3 = new(BiTNode);
    right3->data = 6;
    right3->left = NULL;
    right3->right = NULL;
    left2->left = left3;
    left2->right = right3;
}

void deleteTree(BiTree root)
{
    if(root)
    {
        deleteTree(root->left);
        deleteTree(root->right);
        delete(root);
        root = NULL;
    }
}

int PrintNodeAtLevel(BiTree root, int level)
{
    if(!root || level < 0)
        return 0;
    else if(level == 0)
    {
        cout << root->data << endl;
        return 1;
    }
    else
        return PrintNodeAtLevel(root->left, level - 1) + PrintNodeAtLevel(root->right, level - 1);
}

int main()
{
    BiTree root = new(BiTNode);
    root->data = 0;
    root->right = root->left = NULL;
    createTree(root);    
    cout << "Level 0:" << endl;
    PrintNodeAtLevel(root, 0);
    cout << "-------------------" << endl;
    cout << "Level 1:" << endl;
    PrintNodeAtLevel(root, 1);
    cout << "-------------------" << endl;
    cout << "Level 2:" << endl;
    PrintNodeAtLevel(root, 2);
    cout << "-------------------" << endl;
    cout << "Level 3:" << endl;
    PrintNodeAtLevel(root, 3);
    cout << "-------------------" << endl;
    deleteTree(root);
}
View Code

执行结果

2. 层次遍历二叉树

解法1——根据求得的层次,遍历每一层

参考代码

void TranverseTree(BiTree root)
{
    for(int i = 0; i < Height(root); ++i)
    {
        PrintNodeAtLevel(root, i);
        cout << "_____________________________" << endl;
    }
}

完整执行程序

#include<iostream>
using namespace std;
typedef struct BiTNode
{
    int data;
    BiTNode *left;
    BiTNode *right;
}BiTNode, *BiTree;

int maxDis = 0;

void createTree(BiTree &root)
{
    BiTree left1 = new(BiTNode);
    BiTree right1 = new(BiTNode);
    
    left1->data = 1;
    left1->left = NULL;
    left1->right = NULL;
    right1->data = 2;
    right1->left = NULL;
    right1->right = NULL;

    root->left = left1;
    root->right = right1;


    BiTree left2 = new(BiTNode);
    left2->data = 3;
    left2->left = NULL;
    left2->right = NULL;
    BiTree right2 = new(BiTNode);
    right2->data = 4;
    right2->left = NULL;
    right2->right = NULL;
    left1->left = left2;
    left1->right = right2;

    BiTree left3 = new(BiTNode);
    left3->data = 5;
    left3->left = NULL;
    left3->right = NULL;
    BiTree right3 = new(BiTNode);
    right3->data = 6;
    right3->left = NULL;
    right3->right = NULL;
    left2->left = left3;
    left2->right = right3;
}

void deleteTree(BiTree root)
{
    if(root)
    {
        deleteTree(root->left);
        deleteTree(root->right);
        delete(root);
        root = NULL;
    }
}

int PrintNodeAtLevel(BiTree root, int level)
{
    if(!root || level < 0)
        return 0;
    else if(level == 0)
    {
        cout << root->data << endl;
        return 1;
    }
    else
        return PrintNodeAtLevel(root->left, level - 1) + PrintNodeAtLevel(root->right, level - 1);
}

int Height(BiTree root)
{
    if(root == NULL)
        return 0;
    else
        return Height(root->left) > Height(root->right) ? Height(root->left)+1 : Height(root->right) + 1;
}

void TranverseTree(BiTree root)
{
    for(int i = 0; i < Height(root); ++i)
    {
        PrintNodeAtLevel(root, i);
        cout << "_____________________________" << endl;
    }
}

int main()
{
    BiTree root = new(BiTNode);
    root->data = 0;
    root->right = root->left = NULL;
    createTree(root);    
    TranverseTree(root);
    deleteTree(root);
}
View Code

执行结果

解法2——无需求得层次,根据遍历每层的返回信息确定遍历

参考代码

void TranverseTree(BiTree root)
{
    for(int i = 0; ; ++i)
    {
        if(!PrintNodeAtLevel(root, i))
            break;
        cout << "_____________________________" << endl;
    }
}

完整执行代码

#include<iostream>
using namespace std;
typedef struct BiTNode
{
    int data;
    BiTNode *left;
    BiTNode *right;
}BiTNode, *BiTree;

int maxDis = 0;

void createTree(BiTree &root)
{
    BiTree left1 = new(BiTNode);
    BiTree right1 = new(BiTNode);
    
    left1->data = 1;
    left1->left = NULL;
    left1->right = NULL;
    right1->data = 2;
    right1->left = NULL;
    right1->right = NULL;

    root->left = left1;
    root->right = right1;


    BiTree left2 = new(BiTNode);
    left2->data = 3;
    left2->left = NULL;
    left2->right = NULL;
    BiTree right2 = new(BiTNode);
    right2->data = 4;
    right2->left = NULL;
    right2->right = NULL;
    left1->left = left2;
    left1->right = right2;

    BiTree left3 = new(BiTNode);
    left3->data = 5;
    left3->left = NULL;
    left3->right = NULL;
    BiTree right3 = new(BiTNode);
    right3->data = 6;
    right3->left = NULL;
    right3->right = NULL;
    left2->left = left3;
    left2->right = right3;
}

void deleteTree(BiTree root)
{
    if(root)
    {
        deleteTree(root->left);
        deleteTree(root->right);
        delete(root);
        root = NULL;
    }
}

int PrintNodeAtLevel(BiTree root, int level)
{
    if(!root || level < 0)
        return 0;
    else if(level == 0)
    {
        cout << root->data << endl;
        return 1;
    }
    else
        return PrintNodeAtLevel(root->left, level - 1) + PrintNodeAtLevel(root->right, level - 1);
}

void TranverseTree(BiTree root)
{
    for(int i = 0; ; ++i)
    {
        if(!PrintNodeAtLevel(root, i))
            break;
        cout << "_____________________________" << endl;
    }
}

int main()
{
    BiTree root = new(BiTNode);
    root->data = 0;
    root->right = root->left = NULL;
    createTree(root);    
    TranverseTree(root);
    deleteTree(root);
}
View Code

执行结果

解法3——无需求每次都从根说起,一次遍历成功

可以看出,解法1、2每次都需要从根说起,还可以不从跟谈起,一次遍历所有的节点,不过这需要额外的存储空间

思路

定义两个指针:cur、last.cur指向目前该访问的节点位置,last指向目前队列中最后一个元素的后一个位置

遍历每一层时,遍历每一个元素是cur往后移动,同时把cur指向的左右孩子加入到队列中,当cur==last时说明该层已经遍历完事了。

参考代码

void TranverseTree(BiTree root)
{
    vector<BiTree> vec;
    vec.push_back(root);
    int cur =0, last = 1;
    while(cur < vec.size())
    {
        last = vec.size();
        while(cur < last)
        {
            cout << vec[cur]->data << " ";
            if(vec[cur]->left)
                vec.push_back(vec[cur]->left);
            if(vec[cur]->right)
                vec.push_back(vec[cur]->right);
            ++cur;
        }
        cout << endl;
    }
}

完整执行代码

#include <iostream>
#include <vector>
using namespace std;
typedef struct BiTNode
{
    int data;
    BiTNode *left;
    BiTNode *right;
}BiTNode, *BiTree;

int maxDis = 0;

void createTree(BiTree &root)
{
    BiTree left1 = new(BiTNode);
    BiTree right1 = new(BiTNode);
    
    left1->data = 1;
    left1->left = NULL;
    left1->right = NULL;
    right1->data = 2;
    right1->left = NULL;
    right1->right = NULL;

    root->left = left1;
    root->right = right1;


    BiTree left2 = new(BiTNode);
    left2->data = 3;
    left2->left = NULL;
    left2->right = NULL;
    BiTree right2 = new(BiTNode);
    right2->data = 4;
    right2->left = NULL;
    right2->right = NULL;
    left1->left = left2;
    left1->right = right2;

    BiTree left3 = new(BiTNode);
    left3->data = 5;
    left3->left = NULL;
    left3->right = NULL;
    BiTree right3 = new(BiTNode);
    right3->data = 6;
    right3->left = NULL;
    right3->right = NULL;
    left2->left = left3;
    left2->right = right3;
}

void deleteTree(BiTree root)
{
    if(root)
    {
        deleteTree(root->left);
        deleteTree(root->right);
        delete(root);
        root = NULL;
    }
}

void TranverseTree(BiTree root)
{
    vector<BiTree> vec;
    vec.push_back(root);
    int cur =0, last = 1;
    while(cur < vec.size())
    {
        last = vec.size();
        while(cur < last)
        {
            cout << vec[cur]->data << " ";
            if(vec[cur]->left)
                vec.push_back(vec[cur]->left);
            if(vec[cur]->right)
                vec.push_back(vec[cur]->right);
            ++cur;
        }
        cout << endl;
    }
}

int main()
{
    BiTree root = new(BiTNode);
    root->data = 0;
    root->right = root->left = NULL;
    createTree(root);    
    TranverseTree(root);
    deleteTree(root);
}
View Code

执行结果

C语言写的

void LevelTraverse(BinaryTreeNode *root)
{
    if(root == NULL)
        return;
    BinaryTreeNode* a[MAXSIZE];
    a[0] = root;
    int beg = 0;     //表示该层的第一个元素
    int end = 0;     //表示该层的最后一个元素
    int pos_end = 0; //表示目前访问的元素存放的位置
    while(beg <= end)
    {
        if(a[beg]->m_pLeft != NULL)
            a[++pos_end] = a[beg]->m_pLeft;
        if(a[beg]->m_pRight != NULL)
            a[++pos_end] = a[beg]->m_pRight;
        cout << a[beg]->m_nValue << " ";
        ++beg;
        if(beg > end)
        {
            end = pos_end;
            cout << endl;
        }
    }
}

之字形打印

例子:例子中打印

1
2 3
6 5 4
7

参考

#include <iostream>
#include <vector>
using namespace std;
struct TreeNode 
{
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int v) : val(v), left(NULL), right(NULL){};
};
void LevelTranverse(TreeNode *root)
{
    if (root == NULL)
        return;
    vector<TreeNode *> vec;
    vec.push_back(root);
    int beg = 0; 
    int end = vec.size();
    bool L2R = false;
    while (beg != end)
    {
        if (L2R)
        {
            for(; beg != end; ++beg)
            {
                cout << vec[beg]->val << " ";
                if (vec[beg]->left != NULL)
                    vec.push_back(vec[beg]->left);
                if (vec[beg]->right != NULL)
                    vec.push_back(vec[beg]->right);
            }
        }
        else
        {
            for(int j = beg, k = end-1; k >= beg; ++j, --k)
            {
                cout << vec[k]->val << " ";
                if (vec[j]->left != NULL)
                    vec.push_back(vec[j]->left);
                if (vec[j]->right != NULL)
                    vec.push_back(vec[j]->right);
            }
            beg = end;
        }
        end = vec.size();
        L2R ^= true;
        cout << "
--------------" << endl;
    }
}

    
int main()
{
    TreeNode *root = new TreeNode(0);    
    TreeNode *p1 = new TreeNode(1);    
    TreeNode *p2 = new TreeNode(2);    
    root->left = p1;
    root->right = p2;
    TreeNode *p3 = new TreeNode(3);    
    TreeNode *p4 = new TreeNode(4);    
    p1->left = p3;
    p1->right = p4;
    TreeNode *p5 = new TreeNode(5);    
    TreeNode *p6 = new TreeNode(6);    
    p2->left = p5;
    p2->right = p6;
    TreeNode *p7 = new TreeNode(7);    
    TreeNode *p8 = new TreeNode(8);    
    p3->left = p7;
    p3->right = p8;
    TreeNode *p9 = new TreeNode(9);    
    p4->right = p9;
    LevelTranverse(root);
}
原文地址:https://www.cnblogs.com/kaituorensheng/p/3558645.html