点:技巧性问题
题意:一个二叉树按层的遍历和按层打印
常见面试题
思路:二叉树按层遍历和打印有很多办法,无外乎各种方式做到按层暂存并暂存该层的下一层节点,这样不停的直到树结尾
我的思路是用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;
}