zoukankan      html  css  js  c++  java
  • 层次遍历二叉树(编程之美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);
    }
  • 相关阅读:
    undefined vs. null
    Callback()
    python基础----元类metaclass
    python基础----__next__和__iter__实现迭代器协议
    python基础----析构函数__del__
    python基础----__slots__方法、__call__方法
    python基础----实现上下文管理协议__enter__和__exit__
    python基础----__setitem__,__getitem,__delitem__
    python基础----isinstance(obj,cls)和issubclass(sub,super)、反射、__setattr__,__delattr__,__getattr__、二次加工标准类型(包装)
    python基础----特性(property)、静态方法(staticmethod)、类方法(classmethod)、__str__的用法
  • 原文地址:https://www.cnblogs.com/kaituorensheng/p/3558645.html
Copyright © 2011-2022 走看看