剑指offer第二版32题:从上到下打印二叉树Java


面试题32一共包括三个题目。

一、题目一

题目一:不分行从上到下打印二叉树。
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。例如,输入下图1中的二叉树,则依次打印出8,6,10,5,7,9,11。二叉树节点的定义如下:

public class Node {
		int data;
		Node right;
		Node left;

		Node(int data) {
			this.data = data;
		}
	}

图一:
在这里插入图片描述

1.二叉树的定义

其实题目中的这个例子不是很好,容易让人误解二叉树与二叉排序树的区别。

二叉树的结构是一个父节点挂一个或者两个子节点。
在这里插入图片描述
而且我们要注意到。在左右子节点不为空的情况下,若左子节点小于它的父节点,且右子节点大于它的父节点,那是二叉排序树,不是二叉树。在上网查资料的时候有时会看到一些人将其弄混了。
在这里插入图片描述

2.算法实现

这是我在学习过程中模仿Java集合类写的一个二叉树类,所以把节点类(Node)以内部类的形式写在二叉树类(BinaryTree)的里面。以Integer类为例,如果引入泛型的话,所有类都可以,欢迎大家指导。

BinaryTree类

import java.util.LinkedList;

public class BinaryTree {
	//节点个数
	private int size;
	//根节点
	private Node root;

	public BinaryTree() {

	}

	//有参构造方法
	public BinaryTree(Integer[] c) {
		this();
		root = addAllRecur(c);
	}

	//前序遍历数据创建二叉树(递归)
	private Node addAllRecur(Integer[] c) {
		Integer var = c[size++];
		if (var == null) {
			return null;
		}
		Node node = new Node(var);
		node.left = addAllRecur(c);
		node.right = addAllRecur(c);
		return node;
	}

	//层次遍历
	public void levelOrder() {
		if (root == null) {
			return;
		}
		LinkedList<Node> q = new LinkedList<Node>();
		q.addFirst(root);
		Node current;
		while (!q.isEmpty()) {
			current = q.removeLast();
			System.out.print(current.data + " -> ");
			if (current.left != null)
				q.addFirst(current.left);
			if (current.right != null)
				q.addFirst(current.right);
		}
	}

	private static class Node {

		Integer data;
		Node right;
		Node left;

		Node(Integer data) {
			this.data = data;
		}
	}
}

测试类

public class Demo {

	public static void main(String[] args) {
		//前序遍历建树
		Integer[] arr = { 8, 6, 5, null, null, 7, null, null, 10, 9, null, null, 11, null, null };
		BinaryTree tree = new BinaryTree(arr);

		System.out.print("层次遍历:");
		tree.levelOrder();

	}
}

建立的树:
在这里插入图片描述
测试结果:

层次遍历:8 -> 6 -> 10 -> 5 -> 7 -> 9 -> 11 -> 

其实上面内容是我的一篇文章的截取,有兴趣的可以再看看二叉树(从建树、遍历到存储)Java.这里就不再粘贴复制一遍了。

二、题目二

题目二:分行从上到下打印二叉树。
从上到下按层打印二叉树,同一层的节点按左到右的顺序打印,每一层打印到一行。例如,图二中二叉树的结果为:

8
6 10
5 7 9 11

图二:
在这里插入图片描述

1.分析

这道面试题和前面的面试题类似,也可以用一个队列来保存将要打印的节点。为了把二叉树的每一行单独打印到一行里,我们需要两个变量:一个变量表示当前层中还没有打印的节点数;另一个变量表示下一层节点的数目。

2.算法实现

依然采用上面的形式,把节点类(Node)写成内部类的形式。

BinaryTree类:

import java.util.LinkedList;

public class BinaryTree {
	//节点个数
	private int size;
	//根节点
	private Node root;

	public BinaryTree() {

	}

	//有参构造方法
	public BinaryTree(Integer[] c) {
		this();
		root = addAllRecur(c);
	}

	//前序遍历数据创建二叉树(递归)
	private Node addAllRecur(Integer[] c) {
		Integer var = c[size++];
		if (var == null) {
			return null;
		}
		Node node = new Node(var);
		node.left = addAllRecur(c);
		node.right = addAllRecur(c);
		return node;
	}

	//分行层次遍历
	public void levelOrder() {
		if (root == null) {
			return;
		}
		LinkedList<Node> q = new LinkedList<Node>();
		//当前层还没有打印的节点数
		int toBePrint = 1;
		//下一层节点数
		int nextLevel = 0;
		q.addFirst(root);
		Node current;
		while (!q.isEmpty()) {
			current = q.removeLast();
			System.out.print(current.data + " ");
			toBePrint--;
			if (current.left != null) {
				q.addFirst(current.left);
				nextLevel++;
			}
			if (current.right != null) {
				q.addFirst(current.right);
				nextLevel++;
			}
			if (toBePrint == 0) {
				System.out.println();
				toBePrint = nextLevel;
				nextLevel = 0;
			}
		}
	}

	private static class Node {

		Integer data;
		Node right;
		Node left;

		Node(Integer data) {
			this.data = data;
		}
	}
}

测试类:

public class Demo {

	public static void main(String[] args) {
		//前序遍历建树
		Integer[] arr = { 8, 6, 5, null, null, 7, null, null, 10, 9, null, null, 11, null, null };
		BinaryTree tree = new BinaryTree(arr);

		System.out.println("分层层次遍历:");
		tree.levelOrder();

	}
}

建立的树:
在这里插入图片描述
测试结果:

分层层次遍历:
8 
6 10 
5 7 9 11 

三、题目三

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

1
3 2
4 5 6 7
15 14 13 12 11 10 9 8

图三
在这里插入图片描述

1.分析

《剑指offer第二版》中是用两个栈实现的。

2.算法实现

BinaryTree类:

import java.util.LinkedList;

public class BinaryTree {
	//节点个数
	private int size;
	//根节点
	private Node root;

	public BinaryTree() {

	}

	//有参构造方法
	public BinaryTree(Integer[] c) {
		this();
		root = addAllRecur(c);
	}

	//前序遍历数据创建二叉树(递归)
	private Node addAllRecur(Integer[] c) {
		Integer var = c[size++];
		if (var == null) {
			return null;
		}
		Node node = new Node(var);
		node.left = addAllRecur(c);
		node.right = addAllRecur(c);
		return node;
	}

	//之字形层次遍历(两个栈)
	public void levelOrder() {
		if (root == null) {
			return;
		}
		LinkedList<Node> s1 = new LinkedList<Node>();//奇数行
		LinkedList<Node> s2 = new LinkedList<Node>();//偶数行
		//第几层
		int levelNum = 1;
		Node current;
		s1.addFirst(root);
		while (!s1.isEmpty() || !s2.isEmpty()) {
			//当前行是奇数行
			if (levelNum % 2 != 0) {
				while (!s1.isEmpty()) {
					current = s1.removeFirst();
					System.out.print(current.data + " ");
					if (current.left != null)
						s2.addFirst(current.left);
					if (current.right != null)
						s2.addFirst(current.right);
				}
				levelNum++;
				System.out.println();

			}
			//当前行是偶数行
			else {
				while (!s2.isEmpty()) {
					current = s2.removeFirst();
					System.out.print(current.data + " ");
					if (current.right != null)
						s1.addFirst(current.right);
					if (current.left != null)
						s1.addFirst(current.left);
				}
				levelNum++;
				System.out.println();
			}
		}
	}

	private static class Node {
		Integer data;
		Node right;
		Node left;

		Node(Integer data) {
			this.data = data;
		}
	}
}

测试类:

public class Demo {

	public static void main(String[] args) {
		//前序遍历建树
		Integer[] arr = { 8, 6, 5, null, null, 7, null, null, 10, 9, null, null, 11, null, null };
		BinaryTree tree = new BinaryTree(arr);

		System.out.println("之字形层次遍历:");
		tree.levelOrder();
	}
}

建立的树:
在这里插入图片描述

测试结果:

之字形层次遍历:
8 
10 6 
5 7 9 11 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值