二叉树按层遍历并按层打印和蛇形打印

点:技巧性问题


题意:一个二叉树按层的遍历和按层打印

常见面试题


思路:二叉树按层遍历和打印有很多办法,无外乎各种方式做到按层暂存并暂存该层的下一层节点,这样不停的直到树结尾

我的思路是用2个队列,队列1保存当前层节点,队列2保存当前层下一层的节点,从左节点的左子节点开始,这是对应有些面试题要求保证输出的顺序是从左至右,以及蛇形打印之类的题。


1、按顺序从左到右打印:既然顺序都是从左到右,那么用队列较适合,队列1保存当前层节点用于打印,在遍历打印当前层节点的同时,从左至右依次记录各个节点的左右子节点到队列2,遍历打印完当前层,队列2数据再录入队列1,这样直到队列2不再存在节点

2、按层蛇形打印:用一个栈和一个队列实现,根节点第一层用栈,依次从左到右记录左右子节点到队列,然后第二层队列,依次从左到右记录左右子节点到栈,第三层再用栈.......直到某一层的栈或队列没有再被填充数据为空时,蛇形遍历结束

代码:

#include <iostream>
#include <random>
#include <queue>
#include <stack>

template<class T> struct Node {
    T val;
    Node<T> *lchild;
    Node<T> *rchild;
    Node(T _val):val(_val), lchild(nullptr), rchild(nullptr) {}
};

template<class T> class Btree {
    Node<T> *root;

public:
    Btree ():root(nullptr) {}
    void Free (Node<T> *cur) {
        if (cur) {
            Free(cur->lchild);
            Free(cur->rchild);
            delete cur;
            cur = nullptr;
        }
    }
    ~Btree () {
        Free(root);
    }

    void Add (T val) {
        if (!root) {
            root = new Node<T>(val);
        } else {
            Node<T> *cur = root;
            while (cur) {
                if (cur->val > val) {
                    if (cur->lchild) {
                        cur = cur->lchild;
                    } else {
                        cur->lchild = new Node<T>(val);
                        break;
                    }
                } else if (cur->val < val) {
                    if (cur->rchild) {
                        cur = cur->rchild;
                    } else {
                        cur->rchild = new Node<T>(val);
                        break;
                    }
                } else {
                    break;
                }
            }
        }
    }

    void level_traverse () {
        if (!root) {
            return;
        }
        std::queue<Node<T> *> q1, q2;
        Node<T> *cur = root;
        q1.push(cur);

        while (!q1.empty()) {
            while (!q1.empty()) {
                std::cout << q1.front()->val << "\t";
                if (q1.front()->lchild) {
                    q2.push(q1.front()->lchild);
                }
                if (q1.front()->rchild) {
                    q2.push(q1.front()->rchild);
                }
                q1.pop();
            }
            std::cout << std::endl;
            while (!q2.empty()) {
                q1.push(q2.front());
                q2.pop();
            }
        }
    }

    void shexing_traverse () {
        std::stack<Node<T> *> stk;
        std::queue<Node<T> *> q;
        Node<T> *cur = root;
        stk.push(cur);
        bool flag = false;

        while (1) {
            if (!flag) {
                while (!stk.empty()) {
                    std::cout << stk.top()->val << "\t";
                    if (stk.top()->lchild) {
                        q.push(stk.top()->lchild);
                    }
                    if (stk.top()->rchild) {
                        q.push(stk.top()->rchild);
                    }
                    stk.pop();
                }
                flag = flag?false:true;
                std::cout << std::endl;
                if (q.empty()) {
                    break;
                }
            } else {
                while (!q.empty()) {
                    std::cout << q.front()->val << "\t";
                    if (q.front()->lchild) {
                        stk.push(q.front()->lchild);
                    }
                    if (q.front()->rchild) {
                        stk.push(q.front()->rchild);
                    }
                    q.pop();
                }
                flag = flag?false:true;
                std::cout << std::endl;
                if (stk.empty()) {
                    break;
                }
            }
        }
    }
};

int main () {
    std::random_device rd;
    Btree<int> bt;
    for (int i = 0; i < 15; i++) {
        int cur = rd() % 100;
        std::cout << cur << "\t";
        bt.Add(cur);
    }
    std::cout << std::endl;

    bt.level_traverse();
    bt.shexing_traverse();
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值