剑指offer第二版——面试题32(java)

面试题:从上到下打印二叉树

题目一:

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

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

题目二:

分行,从上到下打印二叉树

题目三:

之字形打印二叉树

 

思路:

题目一:

【方法一】

用一个队列实现,先把根节点加入到队列中

再依次从队列中跳出节点,并将节点的左右结点添加到队列中

每次从队列中跳出节点时打印该结点

【方法二】

用两个队列实现(应该一个队列就可以完成,但是先写了之前的从下往上的,有点崩了QAQ,看以后再写不写吧。。。一个队列的话就是出一个就往队列里放左右结点。。)

 

题目二:

【方法一】

使用【题目一-方法一】的代码进行改进,在每层结尾留下null作为分层的标记

如二叉树8/6 10/5 7 9 11,先加入8,由于8之后就是第二层,因此插入null到队列中

从队列中读出8,并加入8的左右结点6和10,此时队列中为null 6 10,

再从队列中读出null,此时表示该层已经结束,打印换行符,并且因为该层已经结束,因此表示其下一层的所有节点都已经加入到了队列中,添加一个null标记,此时队列中为6 10 null

读出6,打印,并添加6的左右结点5和7,此时队列中为10 null 5 7

读出10,打印,并添加10的左右结点9和11,此时队列中为null 5 7 9 11

读出null,表示该层已经打印结束,打印换行符,并且由于该层已经结束,因此表示下一层的所有节点都已经加入到了队列中,添加一个null标记,此时队列中为5 7 9 11 null

读出5,打印,左右结点为null null,不添加,此时队列中为7 9 11 null 

读出7,打印,并添加7的左右结点,此时队列中为9 11 null 

读出9,打印;读出11,打印,此时队列为null

此处就需要注意:

1)由于使用了null来作为标识符,因此不能在队列中添加其他null,因此在节点添加时需要增加判断是否为null,null不添加

2)由于在最后一个null打印换行符之后,还会添加一个null,所以需要一个flag来判断以跳出循环

 

【方法二】

分行,两个队列实现,轮流用

一个队列用于存要输出的节点,另一个队列用于在输出节点时存放其节点的左右子结点

如第一行为8,第一个队列中存放8。取出8输出时,另一个队列存储6和10.

输出队列中的6和10时,另一个队列依次存放5 7 9 11,两个队列轮流使用,用了temp来进行交换

每次交换队列进行输出时,要进行分行(题目要求)

 

题目三:

用一个栈和一个队列来实现

栈用于从右往左输出,队列用于从左往右输出

如先从根元素8开始,将8先放入栈中,再移除,将子结点6和10放入队列中

从队列中依次读出节点,并往栈中放入节点,即读出6,放入栈中5 7,读出10,放入栈中9 11,此时栈中从上到下为11 9 7 5

从栈中读取节点,并往队列中放入节点,即读出511 9 7 5并依次打印

所以打印顺序为8 6 10 11 9 7 5 

在每次交换栈和队列读取时,打印换行符

 

【数据结构定义和树的构造放在了最后,题目二、三的代码中只放了方法函数】

【题目一】

// 2019-06-21
    public static void printTree(BinaryTreeNode root) {
        Queue<BinaryTreeNode> re = new LinkedList<BinaryTreeNode>();
        re.add(root);
        while(!re.isEmpty()) {
            BinaryTreeNode temp = re.remove();
            if(temp!=null) {
                System.out.printf(temp.val+" ");
                re.add(temp.left);
                re.add(temp.right);
            }
        }
    }
// 2019-05-05
	public static void main(String[] args) {
		BinaryTreeNode root = getTree();
		Print(root);
	}
	
	public static void Print(BinaryTreeNode root) {
		if(root!=null) {
			LinkedList<BinaryTreeNode> save = new LinkedList<BinaryTreeNode>();
			LinkedList<BinaryTreeNode> que = new LinkedList<BinaryTreeNode>();
			que.add(root);
			System.out.printf("que add:%d\n",root.val);
			
			while(!que.isEmpty()) {
				BinaryTreeNode temp = que.remove();
				System.out.printf("sta add:%d\n",temp.val);
				save.add(temp);
				if(temp.leftNode!=null) {
					que.add(temp.leftNode);
				}
				if(temp.rightNode!=null) {
					que.add(temp.rightNode);
				}
			}
			
			while(!save.isEmpty()) {
				System.out.printf("%d ",save.remove().val);
			}
		}
	}

【题目二】

// 2019-06-21 方法一
    public static void printTree(BinaryTreeNode root) {
		Queue<BinaryTreeNode> re = new LinkedList<BinaryTreeNode>();
		re.add(root);
		re.add(null);
		
		boolean flag = false;
		while(!re.isEmpty()) {
			BinaryTreeNode temp = re.remove();
			if(temp!=null) {
				System.out.printf(temp.val+" ");
				
				if(temp.left!=null) {
					re.add(temp.left);
				}
				if(temp.right!=null) {
					re.add(temp.right);
				}
				flag = true;
			}else {
				if(flag==false) {
					break;
				}
				System.out.println();
				re.add(null);
				flag = false;
			}
		}
	}
// 2019-05-05 方法二
    public static void Print(BinaryTreeNode root) {
		if(root!=null) {
			LinkedList<BinaryTreeNode> que1 = new LinkedList<BinaryTreeNode>();
			LinkedList<BinaryTreeNode> que2 = new LinkedList<BinaryTreeNode>();
			que1.add(root);
			
			while(!que1.isEmpty() || !que2.isEmpty()) {
				while(!que1.isEmpty()) {
					BinaryTreeNode temp = que1.remove();
					System.out.printf("%d ",temp.val);
					if(temp.leftNode!=null) {
						que2.add(temp.leftNode);
					}
					if(temp.rightNode!=null) {
						que2.add(temp.rightNode);
					}
				}
				LinkedList<BinaryTreeNode> temp = que2;
				que2 = que1;
				que1 = temp;
				// 用于分行
				System.out.println();
			}
		}
	}

【题目三】

// 2019-06-22
	public static void printTree1(BinaryTreeNode root) {
		if(root==null) {
			return ;
		}
		
		Queue<BinaryTreeNode> queue = new LinkedList<BinaryTreeNode>();
		Stack<BinaryTreeNode> stack = new Stack<BinaryTreeNode>();
		
		int count = 1;
		stack.add(root);

		while(stack.isEmpty() || queue.isEmpty()) {
			if(count%2==1) {
				while(!stack.isEmpty()) {
					BinaryTreeNode t = stack.pop();
					System.out.print(t.val+" ");
					if(t.left!=null) {
						queue.add(t.left);
					}
					if(t.right!=null) {
						queue.add(t.right);
					}
				}
				count++;
			}else {
				while(!queue.isEmpty()) {
					BinaryTreeNode t = queue.remove();
					System.out.print(t.val+" ");
					if(t.left!=null) {
						stack.add(t.left);
					}
					if(t.right!=null) {
						stack.add(t.right);
					}
				}
				count++;
			}
			System.out.println();
			if(stack.isEmpty() && queue.isEmpty()) {
				break;
			}
		}
	}
// 2019-05-05
    public static void Print(BinaryTreeNode root) {
		if(root!=null) {
			LinkedList<BinaryTreeNode> que1 = new LinkedList<BinaryTreeNode>();
			LinkedList<BinaryTreeNode> que2 = new LinkedList<BinaryTreeNode>();
			Stack<BinaryTreeNode> save = new Stack<BinaryTreeNode>();
			que1.add(root);
			int flag = 1;
			while(!que1.isEmpty() || !que2.isEmpty()) {
				while(!que1.isEmpty()) {
					BinaryTreeNode temp = que1.remove();
					if(flag%2==1) {
						save.push(temp);
					}else {
						System.out.printf("%d ",temp.val);
					}
						if(temp.leftNode!=null) {
							que2.add(temp.leftNode);
						}
						if(temp.rightNode!=null) {
							que2.add(temp.rightNode);
						}
				}
				flag++;
				while(!save.empty()) {
					System.out.printf("%d ",save.pop().val);
				}

				LinkedList<BinaryTreeNode> temp = que2;
				que2 = que1;
				que1 = temp;
				// 用于分行
				System.out.println();
			}
		}
	}

 

补:

// 从下往上输出
public class Q32 {
	public static void main(String[] args) {
		BinaryTreeNode root = getTree();
		bottomToUp(root);
	}
	
	public static void bottomToUp(BinaryTreeNode root) {
		if(root!=null) {
			Stack<BinaryTreeNode> sta = new Stack<BinaryTreeNode>();
			LinkedList<BinaryTreeNode> que = new LinkedList<BinaryTreeNode>();
			que.add(root);
			System.out.printf("que add:%d\n",root.val);
			
			while(!que.isEmpty()) {
				BinaryTreeNode temp = que.remove();
				System.out.printf("sta add:%d\n",temp.val);
				sta.push(temp);
				if(temp.rightNode!=null) {
					que.add(temp.rightNode);
				}
				if(temp.leftNode!=null) {
					que.add(temp.leftNode);
				}
			}
			
			while(!sta.empty()) {
				System.out.printf("%d ",sta.pop().val);
			}
		}
	}

 

【树构造】

public static BinaryTreeNode getTree() {
		BinaryTreeNode root = new BinaryTreeNode(8);
		root.leftNode = new BinaryTreeNode(6);
		root.rightNode = new BinaryTreeNode(10);
		BinaryTreeNode root_left = root.leftNode;
		BinaryTreeNode root_right = root.rightNode;
		BinaryTreeNode layer31 = new BinaryTreeNode(5);
		BinaryTreeNode layer32 = new BinaryTreeNode(7);
		BinaryTreeNode layer33 = new BinaryTreeNode(9);
		BinaryTreeNode layer34 = new BinaryTreeNode(11);
		root_left.leftNode = layer31;
		root_left.rightNode = layer32;
		root_right.leftNode = layer33;
		root_right.rightNode = layer34;
		return root;
	}

【数据结构】

public class BinaryTreeNode {
	int val;
	BinaryTreeNode leftNode;
	BinaryTreeNode rightNode;
	public BinaryTreeNode(int x) {
		val = x;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值