剑指Offer-从上到下打印二叉树
题目 1
不分行从上到下打印二叉树。从上到下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印。
示例
输入:
8
/ \
6 10
/ \ / \
5 7 9 11
输出:
8 6 10 5 7 9 11
解题思路
这个其实就是层序遍历。每次打印一个结点的时候,若该结点有子结点,则让该结点的子结点放到一个队列的末尾。接下来到队列的首部取出最早进入队列的结点,不断重复前面的打印,直至队列中所有的结点都被打印出来。
代码实现
#include <iostream>
#include <vector>
#include <queue>
struct BiTNode {
int val;
BiTNode* left;
BiTNode* right;
BiTNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution {
public:
std::vector<int> PrintFromTopToBottom(BiTNode* root) {
// 存储打印结果
std::vector<int> result;
// 边界条件
if (root == nullptr) {
return result;
}
// 辅助容器:队列
std::queue<BiTNode*> qeueTreeNode;
// 根结点入队
qeueTreeNode.push(root);
// 遍历队列
while (!qeueTreeNode.empty()) {
// 辅助指针:指向队头
BiTNode* node = qeueTreeNode.front();
// 打印结果存储到result中
result.push_back(node->val);
// 根结点的子结点入队
if (node->left != nullptr) {
qeueTreeNode.push(node->left);
}
if (node->right != nullptr) {
qeueTreeNode.push(node->right);
}
// 根结点出队
qeueTreeNode.pop();
}
return result;
}
};
// 销毁二叉树
void DestroyBiTree(BiTNode* root)
{
if (root == nullptr) {
return;
}
DestroyBiTree(root->left);
DestroyBiTree(root->right);
// 从最左依次 delete 至根结点
delete root;
root = nullptr;
}
int main(void)
{
Solution sol;
std::vector<int> res;
// 构造一个二叉树
BiTNode* root = new BiTNode(8);
root->left = new BiTNode(6);
root->right = new BiTNode(10);
root->left->left = new BiTNode(5);
root->left->right = new BiTNode(7);
root->right->left = new BiTNode(9);
root->right->right = new BiTNode(11);
res = sol.PrintFromTopToBottom(root);
// 遍历vector,C++ 11 标准支持
for (int i:res) {
std::cout << i;
if (i != res[res.size() - 1]) {
std::cout << ' ';
}
}
// 遍历vector,打印结果
// for (unsigned int i = 0; i < res.size(); ++i) {
// std::cout << res[i];
// if (i != res.size() - 1) {
// std::cout << ' ';
// }
// }
std::cout << std::endl;
DestroyBiTree(root);
return 0;
}
题目 2
分行从上到下打印二叉树。从上到下按层打印二叉树,同一层的结点按从左到右的顺序打印,每一层打印到一行。
示例
输入:
8
/ \
6 10
/ \ / \
5 7 9 11
输出:
8
6 10
5 7 9 11
解题思路
为了把二叉树的每一行单独打印到一行里,我们需要两个变量:一个变量表示当前层中还未打印的结点数;另一个变量表示下一层结点的数目。
代码实现
#include <iostream>
#include <queue>
struct BiTNode {
int val;
BiTNode* left;
BiTNode* right;
BiTNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution {
public:
int PrintTreesInLines(BiTNode* root) {
// 边界条件
if (root == nullptr) {
return -1;
}
std::queue<BiTNode*> qeueTreeNode;
qeueTreeNode.push(root);
// 下一层的结点数
int nextLevel = 0;
// 当前层中未打印的结点数
int toBePrinted = 1;
while (!qeueTreeNode.empty()) {
BiTNode* node = qeueTreeNode.front();
// 打印结果
std::cout << node->val;
// 打印结果之间用空格隔开
if (toBePrinted != 1) {
std::cout << ' ';
}
if (node->left != nullptr) {
qeueTreeNode.push(node->left);
++nextLevel;
}
if (node->right != nullptr) {
qeueTreeNode.push(node->right);
++nextLevel;
}
qeueTreeNode.pop();
--toBePrinted;
// 当前层的所有结点已打印完毕,可以继续打印下一层
if (toBePrinted == 0) {
std::cout << std::endl;
toBePrinted = nextLevel;
nextLevel = 0;
}
}
return 0;
}
};
// 销毁二叉树
void DestroyBiTree(BiTNode* root)
{
if (root == nullptr) {
return;
}
DestroyBiTree(root->left);
DestroyBiTree(root->right);
// 从最左依次 delete 至根结点
delete root;
root = nullptr;
}
int main(void)
{
Solution sol;
// 构造一个二叉树
BiTNode* root = new BiTNode(8);
root->left = new BiTNode(6);
root->right = new BiTNode(10);
root->left->left = new BiTNode(5);
root->left->right = new BiTNode(7);
root->right->left = new BiTNode(9);
root->right->right = new BiTNode(11);
sol.PrintTreesInLines(root);
std::cout << std::endl;
DestroyBiTree(root);
return 0;
}
题目 3
之字形打印二叉树。请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二行按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其它行以此类推。
示例
输入:
1
/ \
2 3
/ \ / \
4 5 6 7
/ \ / \ / \ / \
8 9 10 11 12 13 14 15
输出:
1
3 2
4 5 6 7
15 14 13 12 11 10 9 8
解题思路
按之字形顺序打印二叉树需要两个栈。在打印某一层的结点时,把下一层的子结点保存到相应的栈里。若当前打印的是奇数层(第 1 、3 层等),则先保存左子结点再保存右子结点到第一个栈里;若打印的是偶数层(第 2 、4层等),则先保存右子结点再保存左子结点到第二个栈里。
代码实现
#include <iostream>
#include <stack>
struct BiTNode {
int val;
BiTNode* left;
BiTNode* right;
BiTNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution {
public:
int PrintTreesInZigzag(BiTNode* root) {
// 边界条件
if (root == nullptr) {
return -1;
}
std::stack<BiTNode*> stackLevels[2];
int current = 0;
int next = 1;
stackLevels[current].push(root);
while (!stackLevels[0].empty() || !stackLevels[1].empty()) {
BiTNode* node = stackLevels[current].top();
stackLevels[current].pop();
std::cout << node->val;
if (!stackLevels[current].empty()) {
std::cout << ' ';
}
if (current == 0) {
if (node->left != nullptr) {
stackLevels[next].push(node->left);
}
if (node->right != nullptr) {
stackLevels[next].push(node->right);
}
} else {
if (node->right != nullptr) {
stackLevels[next].push(node->right);
}
if (node->left != nullptr) {
stackLevels[next].push(node->left);
}
}
if (stackLevels[current].empty()) {
std::cout << std::endl;
current = 1 - current;
next = 1 - next;
}
}
return 0;
}
};
// 销毁二叉树
void DestroyBiTree(BiTNode* root)
{
if (root == nullptr) {
return;
}
DestroyBiTree(root->left);
DestroyBiTree(root->right);
// 从最左依次 delete 至根结点
delete root;
root = nullptr;
}
int main(void)
{
Solution sol;
// 构造一个二叉树
BiTNode* root = new BiTNode(1);
root->left = new BiTNode(2);
root->right = new BiTNode(3);
root->left->left = new BiTNode(4);
root->left->right = new BiTNode(5);
root->right->left = new BiTNode(6);
root->right->right = new BiTNode(7);
root->left->left->left = new BiTNode(8);
root->left->left->right = new BiTNode(9);
root->left->right->left = new BiTNode(10);
root->left->right->right = new BiTNode(11);
root->right->left->left = new BiTNode(12);
root->right->left->right = new BiTNode(13);
root->right->right->left = new BiTNode(14);
root->right->right->right = new BiTNode(15);
sol.PrintTreesInZigzag(root);
std::cout << std::endl;
DestroyBiTree(root);
return 0;
}
个人主页: