剑指offer系列-面试题32_2-之字形打印二叉树(python)

之字形打印二叉树
本文介绍了一种特殊的二叉树遍历方式——之字形打印,并提供了两种不同的实现思路,一种使用队列,另一种使用栈。通过对比这两种方法,分析了它们的时间和空间复杂度。

1. 题目

请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行在按照从左到右的顺序打印,其他行以此类推。例如,按之字形顺序打印下图中的二叉树。


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

2. 解题思路

2.1 我的思路

使用的容器不变,仍然使用队列来实现。根据节点所处层数的不同而修改元素添加的顺序,打印的时候仍然顺序打印出来。

我们需要三个变量:

一个变量表示在当前层中还没有打印的节点数;
一个变量表示下一层节点的数目。
一个变量来记录这是第几行,奇数行如何如何,偶数行如何如何。

2.2 书中的思路

不使用队列来实现,而是使用栈来实现,而元素添加的顺序仍然需要考虑所处的层数。

这里是引用

3. 代码实现

3.1 我的思路

def print_binarytree(root):
	"""
	:param root: 二叉树的根节点
	:return None
	"""
	if not root:
		return 
	queue = [] # 队列
	queue.append(root)
	to_be_print = 1 # 表示当前层中还没有打印的节点数
	next_level = 0 # 表示下一层节点的数目
	level = 1 # 第几层
	while queue:
		cur_node = queue.pop(0) # 时间复杂度为O(n)
		print(cur_node.value)
		if level % 2: # 奇数,从左到右打印
			if cur_node.left:
				queue.append(cur_node.left)
				next_level += 1 # 下一层有左子节点,下一层节点数目+1
			if cur_node.right:
				queue.append(cur_node.right)
				next_level += 1 # 下一层有右子节点,下一层节点数目+1
		else:
			if cur_node.right:
				queue.append(cur_node.right)
				next_level += 1 # 下一层有右子节点,下一层节点数目+1
			if cur_node.left:
				queue.append(cur_node.left)
				next_level += 1 # 下一层有左子节点,下一层节点数目+1
			
		# 每打印一个节点,to_be_print减1
		to_be_print -= 1
		# 如果to_be_print == 0表示这一层已经打印完毕,需要打印下一行了
		if to_be_print == 0:
			print('\n') # 换行 
			level += 1
			to_be_print = next_level # 下一层需要打印的节点数变成了当前层中还没有打印的节点数
			next_levle = 0 # 同时清零下一层需要打印的节点数

3.2 书中的思路

def print_binarytree(root):
	"""
	:param root: 二叉树的根节点
	:return None
	"""
	if not root:
		return 
	#level = 1 # 第几层
	cur_stack = [] # 栈
	next_stack = [] # 栈
	cur_stack.append(root)
	while cur_stack:
		cur_node = cur_stack.pop() # 后进先出,时间复杂度为O(n)
		print(cur_node.value)
	
		if level % 2: # 下一层的元素需要从右往左打印,因此先压左子节点入栈,再压右子节点入栈
			if cur_node.left:
				next_stack.append(cur_node.left)
			if cur_node.right:
				next_stack.append(cur_node.right)
		else:
			if cur_node.right:
				next_stack.append(cur_node.right)
			if cur_node.left:
				next_stack.append(cur_node.left)

		if not cur_stack: # 这一层的栈空了之后,交换这两个栈
			cur_stack, next_stack = next_stack, cur_stack
			

4. 总结

队列和栈都可以实现这个题,但是选择不同的容器来实现,最后的时间复杂度和空间复杂是不一样的,就这道题而言,明显使用栈来实现的,时间复杂度更低(主要是低在弹出需要打印的元素这一步,队列这一步时间复杂度为O(n), 而栈这一步的时间复杂度为O(1))。

5. 参考文献

[1] 剑指offer丛书

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值