题目描述
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
这个明显就是层序遍历二叉树,需要借助队列实现,之前在剑指 offer_面试题6_重建二叉树 中已经写了3种二叉树的遍历算法,其中层序遍历使用了双端队列deque和数组模拟队列两种方法,本次采用数组循环队列法,当是复习数据结构吧。
这里约定:
队头指针 front 指向队头元素,队尾指针 rear 指向队尾元素的下一个位置(也可以反过来规定)。
循环队列三种方式区分队空队满:
(1) 牺牲一个存储单元。
(2)增加size成员,记录长度
(3)增加标志位,判断上一次操作时入队还是出队
这里采用牺牲一个存储单元法来区分队空队满。
二叉树相关定义及构建方式:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <iostream>
#include <vector>
static const int MaxSize = 1024;
using namespace std;
//二叉树
typedef struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
} TreeNode;
//剑指offer原书版,根据先序遍历序列、中序遍历序列重建二叉树
TreeNode* ConstructByPreIn(int *preOrder, int *inOrder, int length)
{
if (preOrder == NULL || inOrder == NULL || length <= 0) return NULL;
//新建结点,当前先序序列第一个元素为根结点
int root_val = preOrder[0];
TreeNode *root = new TreeNode(root_val);
//初始化左右子树参数
int leftLength = 0;
int rightLength = 0;
//在中序序列中找到根节点的位置(必存在)
for (int i = 0; i < length; i++)
{
if (inOrder[i] == root_val)
{
leftLength = i;
rightLength = length - i - 1;
break;
}
}
//中序序列中,根节点左边的为左子树,右边的为右子树
int *leftPre = preOrder + 1;
int *leftIn = inOrder;
int *rightPre = preOrder + leftLength + 1;
int *rightIn = inOrder + leftLength + 1;
//递归构建左右子树
root->left = ConstructByPreIn(leftPre, leftIn, leftLength);
root->right = ConstructByPreIn(rightPre, rightIn, rightLength);
return root;
}
循环队列定义:
//循环队列
template <typename T>
class CiQueue{
private:
T data[MaxSize];
int m_front, m_rear;
public:
CiQueue() : m_front(0), m_rear(0) {}
bool push(const T& value)
{
if ((m_rear + 1) % MaxSize == m_front) return false; //队满
data[m_rear] = value;
m_rear = (m_rear + 1) % MaxSize;
}
bool pop()
{
if (isEmpty()) return false; //队空
m_front = (m_front + 1) % MaxSize;
return true;
}
bool isEmpty()
{
return m_front == m_rear;
}
const T& front() {
assert(!isEmpty());
return data[m_front];
}
};
主程序:
//层序二叉树
vector<int> PrintFromTopToBottom(TreeNode* root) {
vector<int> result;
if (root)
{
CiQueue<TreeNode*> queue;
queue.push(root);
while (!queue.isEmpty())
{
TreeNode *node = queue.front();
result.push_back(node->val);
queue.pop();
if (node->left)
queue.push(node->left);
if (node->right)
queue.push(node->right);
}
}
return result;
}
int main()
{
int preOrder[] = { 1,2,4,7,3,5,6,8 };
int inOrder[] = {4,7,2,1,5,3,8,6};
TreeNode *tree = ConstructByPreIn(preOrder, inOrder, 8);
vector<int> result = PrintFromTopToBottom(tree);
for (int e : result)
cout << e << " ";
cout << endl;
getchar();
return 0;
}
效果图: