剑指offer 32. 从上到下打印二叉树

声明:本系列博客是对何海涛《剑指offer》的关键点总结。

1.不分行从上到下打印二叉树

1.1. 问题描述

从上到下打印出二叉树的每一个结点,同一层的结点按照从左到右的顺序打印。

如二叉树(8(6(5,7),10(9,11)))打印出8 6 10 5 7 9 11

1.2. 解决思路

1)使用队列保存要访问的结点;

2)从根结点开始,每次打印结点的时候,如果该结点有子结点,则把该结点的子结点放入队列的末尾。

3)从队列的头部取出最早放进去的结点,重复2)直到队列中所有的结点被打印出来。

1.3. 代码实现

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
    //构造函数使用列表法初始化数据成员。c++允许在struct内定义成员函数,c语言不允许
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};*/
class Solution {
public:
    vector<int> PrintFromTopToBottom(TreeNode* root) {
        vector<int> res;
        queue<TreeNode*> q;
        if (root == NULL)
            return res;        
        q.push(root);
        while(q.size() != 0){
            TreeNode* node = q.front();
            q.pop();
            res.push_back(node->val);
            if(node->left != NULL)
                q.push(node->left);
            if(node->right != NULL)
                q.push(node->right);
        }
       return res; 

    }
};

2.分行从上到下打印二叉树

2.1 问题描述

从上到下打印出二叉树的每一个结点,同一层的结点按照从左到右的顺序打印,每一层打印到一行。

如二叉树(8(6(5,7),10(9,11)))打印出:

6 10 

5 7 9 11

2.2 解决思路

在问题1的基础上,添加两个变量:

int toBePrinted:表示当前层中还有多少个需要打印;

int nextLevelNum:表示下一层结点的数目;

2.3 代码实现

与问题1的差异用//*****标记

struct BinaryTreeNode {
	int value;
	BinaryTreeNode* pLeft;
	BinaryTreeNode* pRight;
};

void PrintFromTopToBottom(BinaryTreeNode * pTreeRoot){
	if (!pTreeRoot)
		return;
	int toBePrinted = 1;//*****
	int nextLevelNum = 0;//*****
	queue<BinaryTreeNode*> q;
	q.push(pTreeRoot);
	while (!q.empty()){
		BinaryTreeNode * pNode = q.front();
		q.pop();
		toBePrinted--;//*****
		cout << pNode->value << " ";
		if (pNode->pLeft){
			q.push(pNode->pLeft);
			nextLevelNum++;//*****

		}
		if (pNode->pRight){
			q.push(pNode->pRight);
			nextLevelNum++;//*****
		}
		//*****控制转行输出
		if (toBePrinted == 0){
			cout << endl;
			toBePrinted = nextLevelNum;
			nextLevelNum = 0;
		}
	}
}

3. 之字形打印二叉树

3.1 问题描述

 

3.2 解决思路

根绝问题描述可知,奇数层从左到右打印,偶数层从右到左打印,即先访问的结点,其子结点反而是后打印的,所以是一个明显的后进先出结构,需要借助两个栈来完成。

1)如果打印的是奇数层从左到右),使用1表示奇数,则在第一个栈中,先保存其左子结点,后保存右子结点;

2)如果打印的是偶数层从右到左),使用0表示偶数则在第二个栈中,先保存其右子结点,后保存左子结点;

3.3 代码实现

struct BinaryTreeNode {
	int value;
	BinaryTreeNode* pLeft;
	BinaryTreeNode* pRight;
};

void PrintFromTopToBottom(BinaryTreeNode * pTreeRoot)
{
	if (!pTreeRoot)
		return;

	stack<BinaryTreeNode*> istack[2];
	int current = 1;//1表示奇数层,与0不停更替
	int next = 0;//0表示偶数层,与1不停更替
	istack[current].push(pTreeRoot);

	while (!istack[0].empty() && !istack[1].empty())
	{
		BinaryTreeNode * pNode = istack[current].top();
		istack[current].pop();
		cout << pNode->value << " ";

		//奇数层先保存左结点,后保存右结点
		if (current == 1)
		{
			if (pNode->pLeft)
				istack[next].push(pNode->pLeft);
			if (pNode->pRight)
				istack[next].push(pNode->pRight);

		}

		//偶数层先保存右结点,后保存左结点
		else
		{
			if (pNode->pRight)
				istack[next].push(pNode->pRight);
			if (pNode->pLeft)
				istack[next].push(pNode->pLeft);
		}
		//判断是否转行进入下一层
		if (istack[current].empty())
		{
			cout << endl;
			current = 1 - current;
			next = 1 - next;


		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值